[JAVA-4510] PowerOfTwoBufferPool leaks permits when compression is enabled Created: 01/Mar/22  Updated: 28/Oct/23  Resolved: 03/Mar/22

Status: Closed
Project: Java Driver
Component/s: Internal
Affects Version/s: 3.12.10, 4.5.0
Fix Version/s: 4.5.1, 3.12.11

Type: Bug Priority: Major - P3
Reporter: Konstantin Labun Assignee: Valentin Kavalenka
Resolution: Fixed Votes: 0
Labels: external-user
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File Screen Shot 2022-02-25 at 11.30.53 PM.png    
Issue Links:
Related
Backwards Compatibility: Fully Compatible
Documentation Changes: Not Needed

 Description   

Summary

InternalStreamConnection doesn't release buffers returned by PowerOfTwoBufferPool when compression is enabled. It leads to permits leakage. After Integer.MAX_VALUE buffer retrievals buffer pool is fully exhausted and all following requests would be blocked indefinitely unless thread get interrupted. 

How to Reproduce

Code below simulate the problem but require significant amount of time to exhaust the pool. I would recommend to run it for some time and take a heap dump. Search for ConcurrentPool instances in heap dump and check for permits number. It will be equal to Integer.MAX_VALUE minus number of requests made. See attachments for an example.

        MongoClientSettings settings = MongoClientSettings.builder()
                .compressorList(singletonList(MongoCompressor.createZlibCompressor()))
                .build();
 
        MongoClient mongo = MongoClients.create(settings);
        MongoDatabase db = mongo.getDatabase("test");
        MongoCollection<Document> collection = db.getCollection("JAVA4510");
        
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        List<Future<?>> tasks = new ArrayList<>();
        BasicDBObject searchQuery = new BasicDBObject();
        searchQuery.put("_id", 1);
        for (long i = 0; i <= Integer.MAX_VALUE; i += 1_000) {
            for (long j = 0; j < 1_000; j++) {
                tasks.add(executorService.submit(() -> {
                    collection.find(searchQuery).first();
                }));
                for (Future<?> task : tasks) {
                    task.get();
                }
                tasks.clear();
            }
        }
 
        executorService.shutdownNow();
        collection.find(searchQuery);



 Comments   
Comment by Jeffrey Yemin [ 23/Mar/22 ]

FYI, 4.5.1 has been released with a fix for this issue.

Comment by Githook User [ 03/Mar/22 ]

Author:

{'name': 'Konstantin Labun', 'email': 'kulabun@users.noreply.github.com', 'username': 'kulabun'}

Message: ByteBuffer is not released when compression is enabled, causing pool leakage (#883)

JAVA-4510

Co-authored-by: Konstantin Labun <konstantinlabun@Konstantins-Air.Home>
Co-authored-by: Valentin Kovalenko <valentin.kovalenko@mongodb.com>
Branch: 3.12.x
https://github.com/mongodb/mongo-java-driver/commit/aa5824a2ecb57a9043a0dbf814e1867b777e1312

Comment by Githook User [ 03/Mar/22 ]

Author:

{'name': 'Konstantin Labun', 'email': 'kulabun@users.noreply.github.com', 'username': 'kulabun'}

Message: ByteBuffer is not released when compression is enabled, causing pool leakage (#883)

JAVA-4510

Co-authored-by: Konstantin Labun <konstantinlabun@Konstantins-Air.Home>
Co-authored-by: Valentin Kovalenko <valentin.kovalenko@mongodb.com>
Branch: 4.5.x
https://github.com/mongodb/mongo-java-driver/commit/2856ca179fee583d5b9e9c76e14455c716bc7d88

Comment by Githook User [ 03/Mar/22 ]

Author:

{'name': 'Konstantin Labun', 'email': 'kulabun@users.noreply.github.com', 'username': 'kulabun'}

Message: ByteBuffer is not released when compression is enabled, causing pool leakage (#883)

JAVA-4510

Co-authored-by: Konstantin Labun <konstantinlabun@Konstantins-Air.Home>
Co-authored-by: Valentin Kovalenko <valentin.kovalenko@mongodb.com>
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/d89ed7eb12c571df3b3cc2c4fcf71bcc39bde4a7

Comment by Jeffrey Yemin [ 02/Mar/22 ]

This is a great find, and surprising that no one has run into this before.  Thanks also for the PR.  It looks good at first glance and we'll try to get it merged and released in 4.5.1 ASAP.

Comment by Konstantin Labun [ 02/Mar/22 ]

Please check the merge request https://github.com/mongodb/mongo-java-driver/pull/883

Generated at Thu Feb 08 09:02:16 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.