JVM Heap Memory Management
858646Apr 29 2011 — edited May 4 2011Hi,
In the real world, we have an application which use about 150m on heap after startup, but some task can make the memory grow up to 700m.
The problem is that after the "memory consuming" task, the JVM don't release it.
We made some test with Java Visual VM, with different garbage collector and -XX:MaxHeapFreeRatio= -XX:MinHeapFreeRatio= values, and finally write a little application to test various case.
The mini app can be found here : http://pastebin.com/tuiEJaMA
For testing purpose, we run it with very little value for heap-ratio here is our testing command line : -Xmx1224m -XX:MaxHeapFreeRatio=2 -XX:MinHeapFreeRatio=2
For now, we was able to see a real allocated memory shrink in two conditions :
- Manual call to System.gc() soon after use-memory/free clicking.
- Spamming call to System.gc() if you wait about ten second after use-memory/free clicking.
In other case, the GC seem to pass only on even space, doesn't see that the byte array is not referenced anymore, and real allocated memory grow up for each use-memory call.
Worst, 1 click to call explicitly System.gc() free internally the use memory, but do not return unused memory to the system (doesn't follow the -XX:MaxHeapFreeRatio=2 directive).
So, here is my question : How can I be sure after a memory consuming task that the JVM won't keep the memory for itself when the really used memory is about 150m and the allocated size is about 1gb ? is there any clean way to notify the JVM that this memory usage was really temporary and that it should release it for other application ?
At this time, the only solution I see will be to use "the spam System.gc()" technique, because in our little testCase, it was the only way to reprodruce a memory freeing at system level. But this solution seems more than dirty to me.