[JAVA-1880] Higher memory allocation rate for write commands than write protocol Created: 04/Jul/15  Updated: 16/Aug/16  Resolved: 09/Jul/15

Status: Closed
Project: Java Driver
Component/s: Performance
Affects Version/s: 2.12.5, 2.13.2
Fix Version/s: 2.13.3, 2.14.0

Type: Improvement Priority: Major - P3
Reporter: John Morales Assignee: Jeffrey Yemin
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Driver 2.13.2
Oracle JDK 1.8


Attachments: PNG File allocation_new_tlab.png     PNG File allocation_outside_tlab.png    
Issue Links:
Related

 Description   

TL;DR
In the 2.13.x driver, the write command paths do not leverage the Mongo client's PoolOutputBuffer pool while the write protocol codepaths do.

Details
The Mongo client instance maintains a _bufferPool of 1000 PoolOutputBuffer's.

For write protocol operations
When talking to a <=2.4 mongod, or using UNACKNOWLEDGED writes to a >=2.6 mongod, this _bufferPool is used to provide a PoolOutputBuffer for both encoding the write as well as reading the response (OutMessage).

For write command operations
Sending the op to the mongod (sendWriteCommandMessage()) and receiving the response (receiveWriteCommandMessage(() creating a new DefaultDBDecoder) each create in a new unpooled PoolOutputBuffer.

The consequence is that while PoolOutputBuffer does contains a static pool of "extra" byte arrays which are used for growing, each PoolOutputBuffer instance still has a minimum 32KB allocation for the _mine and _chars buffers – a nontrivial amount per operation.

Consider the following flight recorder sample:

The above shows for allocations in TLAB by class, char[] and byte[] contribute to 50%+ of all allocation pressure. And for this application, 43% of the char[] allocations are from PoolOutputBuffer on the write command paths. (Not shown above, but 83% of byte[] is PoolOutputBuffer.)

Again for this write-heavy application anyway, outside TLAB pressure shows even higher pressure:

Here we see the byte[] and char[] combine to ~93% of all allocation pressure, and the majority of each again as PoolOutputBuffer on write command paths (83% and 93%, respectively).



 Comments   
Comment by Githook User [ 09/Jul/15 ]

Author:

{u'username': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'}

Message: For write commands, use buffer pool for encoding and the DBPort's decoder for decoding. By using pooled buffers instead of short-lived ones,
memory pressure is reduced.

JAVA-1880
Branch: 2.x
https://github.com/mongodb/mongo-java-driver/commit/3020e7bd3c3582051c13259bc2c06895b8afc96e

Comment by Githook User [ 09/Jul/15 ]

Author:

{u'username': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'}

Message: For write commands, use buffer pool for encoding and the DBPort's decoder for decoding. By using pooled buffers instead of short-lived ones,
memory pressure is reduced.

JAVA-1880
Branch: 2.13.x
https://github.com/mongodb/mongo-java-driver/commit/1e81245457cc29a6b35f34c9bdfcb0d74a5d657c

Generated at Thu Feb 08 08:55:45 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.