简体   繁体   中英

Impossible Java memory references in Heap Dump

I have a Java Heap Dump taken at 7:41pm which I am analysing with Eclipse Memory Analysis Tool. The heap dump includes 20 session objects.

Using the Path to GC Roots command on one of these session objects in my heap shows the following 3 references to the session object.

  • A finalizer reference from the "unfinalized" linked list owned by the Finalizer thread. My object is 3rd in line to be finalized.
  • A strong reference to the session object from a message handler thread which is itself referenced from a cleanup TimerTask scheduled to run at 7:11pm.
  • A weak reference to the session object from a WeakHashMap$Entry. The WeakHashMap is kept alive by a static strong reference.

How can the session object be on the finalizer queue when it still has a strong and a weak reference?

Of the remaining 19 session objects, 1 more is in the finalizer queue and has a similar weak reference. All the other 18 session objects are only weakly referenced. Why hasn't the GC cleared these weak refs?

A few general points:

  • Objects are only eligible for finalization AFTER their weak refs have been cleared (http://download.oracle.com/javase/6/docs/api/java/lang/ref/package-summary.html)
  • The session object does not have a finalizer which could resurrect it and even if it did it couldn't have been run while the object is still in the unfinalized queue behind other objects.
  • My application doesn't use Phantom refs which are the only refs which should be able to exist once an object is eligible for finalization. Even if my app did use phantom refs these objects do not expose their reference to the object they hold.

I think the mistake you're making here is in this part:

A finalizer reference from the "unfinalized" linked list owned by the Finalizer thread. My object is 3rd in line to be finalized.

If you're talking about this:

static private Finalizer unfinalized = null;

in Sun's Finalizer.java (a Finalizer contains a next and prev Finalizer , hence the 'linked list' part, for those playing along at home), then that's not the list of things to be finalized.

Finalizer.add() is not (as I think you're assuming) called during the finalization process, when the object is unreachable; rather, that method is called at creation time of the Object (eg during <init> , by native code, for any Object which overrides finalize() .

The presence of a Finalizer in the next chain doesn't mean it's about to be finalized; it's the

static private ReferenceQueue queue

which holds such objects. Being in the linked list just means that it has a finalize() method.

Therefore your first point is a red herring, it's your second point that's keeping the item reachable, and the third point flows from the second (because the WeakReference won't be cleared while the object is reachable).

Hope this helps!

Weak references are only an indication for the GC. You have no hard guarantees when it will be cleared up.

You can make an object scheduled for finalize available again.

I know about:

The session object does not have a finalizer which could resurrect it and even if it did it couldn't have been run while the object is still in the unfinalized queue behind other objects.

However there might be other objects doing so (ie having ref to the Session and getting themselves rez'd). Either way show the finalizer of that Session thingie.

notes: before clearing the phantom refs the Object WILL NOT be available for finalization. (Phantom references are most often used for scheduling pre-mortem cleanup actions, javadoc ), pre (not post like Weak ones).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM