I\'am struggling with unreachable objects in my JVM heap (Java 1.7). As you can see from the picture (all classes on the picture are unreachable), we have more than 74 % objects
One possibility is that you are overloading the JVM with pathological behavior in finalize()
methods. If you have classes that override Object.finalize()
the JVM has to do a surprising amount of work in order to actually clean them up (and, in turn, clean up all their referenced objects). If you create such objects faster than the garbage collector can process them you'll quickly run into trouble.
This article walks through a pathological finalizer example in detail, but to summarize:
finalize()
method falls out of scope and (conceptually) becomes eligible for GC.finalize()
.Finalizer
thread, which will call .finalize()
on each object in turn. Objects that haven't yet had their turn remain on the heap though they're unreachable.Finalizer
thread this last reference is removed and the object can finally actually be GC'ed. Since the object survived one or more collection rounds it may take some time for the GC to get around to it.If your .finalize()
methods take a particularly long time or if you're creating a large number of such objects the Finalizer
thread can't keep up with the demand and objects will continue to queue up, eventually filling your entire heap.
There are other possible explanations, but over-use of finalize()
is a likely reason. Effective Java Item 7 strongly discourages finalizers:
Finalizers are unpredictable, often dangerous, and generally unnecessary. Their use can cause erratic behavior, poor performance, and portability problems....
Providing a finalizer for a class can, under rare conditions, arbitrarily delay reclamation of its instances.