Unreachable objects are not garbage collected from heap

前端 未结 3 1858
予麋鹿
予麋鹿 2021-02-14 04:48

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

3条回答
  •  独厮守ぢ
    2021-02-14 05:09

    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:

    1. An object with a finalize() method falls out of scope and (conceptually) becomes eligible for GC.
    2. Unlike a normal object which can simply be freed, the JVM holds a special reference to the object via a Finalizer, preventing these objects from being trivially collected. Even short-lived objects survive the initial GC and move into longer-lived sections of the heap if associated with a finalize().
    3. Now these objects will be processed by the dedicated 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.
    4. Once the object is processed by the 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.
    5. Any objects the finalizable object referenced in turn are only now eligible for collection.

    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.

提交回复
热议问题