开发者

Impossible Java memory references in Heap Dump

开发者 https://www.devze.com 2023-02-03 20:33 出处:网络
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.

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开发者_如何学Python 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 (e.g. 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 (i.e. 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).

0

精彩评论

暂无评论...
验证码 换一张
取 消