I have an application that builds up a large Heap. Eventually the whole heap gets placed in the applications Old Generation, unable to be garbage collected.
Analyzing a heap dump with the Eclipse Memory Analyzer reports:
63,029 instances of "com.sleepycat.je.tree.BIN", loaded by "org.eclipse.jetty.webapp.WebAppClassLoader @ 0x7ffa3b0028c8" occupy 761,869,552 (79.94%) bytes. These instances are referenced from one instance of "com.sleepycat.je.tree.Node", loaded by "org.eclipse.jetty.webapp.WebAppClassLoader @ 0x7ffa3b0028c8"
7,595 instances of "com.sleepycat.je.tree.DBIN", loaded by "org.eclipse.jetty.webapp.WebAppClassLoader @ 0x7ffa3b0028c8" occupy 107,676,552 (11.30%) bytes. These instances are referenced from one instance of "java.util.concurrent.ConcurrentHashMap$Segment", loaded by "<system class loader>"
Is there any way that I can analyze why the memory is retained, and how to ensure that the amount of object kept in memory is reduced ?
The project is Open Source, and the code for the class that holds on to the Berkely Environment: https://github.com/joachimhs/EurekaJ/blob/master/EurekaJ.BerkeleyPlugin/src/main/java/org/eurekaj/berkeley/db/BerkeleyDbEnv.java
Any help and tips as to how to move forward will be very much appreciated.
I suspect you are seeing the objects kept in the JE cache. You could reduce the cache size, but that will of course reduce performance. If you want to clear the cache, you could close the Environment, but I doubt that's what you really want.
The point is that the JE cache is intended to hold onto memory. That's what a cache does. The objects you mentioned earlier are in the cache. There isn't a leak, that we know of. If there isn't enough room left in the heap for efficient GC, reduce the size of the JE cache or increase the size of the heap.