Reputation: 37
I have a java process which creates a short lived thread and a short live direct byte buffer in them continuously every 10 milliseconds which is eating up system memory. Though the byte buffers are short-lived, they are not getting cleaned up.
I root caused the issue and added maxDirectMemorySize and also maxCacheBufferSize
too, although it still exhibits the same behavior.
Is it because of maxCacheBufferSize
? I mean every thread is allocating a direct memory equivalent to maxCacheBufferSize
?
-XX:MaxDirectMemorySize=256M
-Djdk.nio.maxCachedBufferSize=262144
while(true) {
for (int i=0; i<100; i++) {
es.execute(() -> {
try {
ByteBuffer buffer = ByteBuffer.allocateDirect(2048);
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
}
Upvotes: 0
Views: 5216
Reputation: 59253
On the Java heap, a direct byte buffer is a very small object that just has a pointer to the native array...
As the Java heap gets full, GC will clean up those small objects, and when those small objects get cleaned up, the native arrays will be freed...
But it takes a LOT of those very small objects to fill up the Java heap. If amount of memory you're churning through on the Java heap is small compared to the amount you're using on the system heap, then those native arrays can hang around a long time and eat up a lot of system memory.
You should just not have a bunch of short-lived direct-allocated buffers. You should probably just use heap-allocated buffers, or recycle the direct-allocated buffers so that they can be reused instead of allocating new ones.
Upvotes: 2