When object with non-trivial finalize()
method is created, JVM will create Finalizer
(FinalReference
) with this object as referent. What will happen if this object will be also wrapped by Soft/Weak or Phantom Reference? Would GC try to enqueue the Finalizer
(call finalize method on it) at first, and then enqueue the other Reference or the opposite?
I think, your question is not about the time of enqueuing, actually.
Consider the Notification section of the package documentation
Some time after the garbage collector determines that the reachability of the referent has changed to the value corresponding to the type of the reference, it will add the reference to the associated queue.
(Note the “some time after”)
and likewise, all reference types have a statement of the form:
Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references. At the same time it will declare all of the formerly weakly-reachable objects to be finalizable. At the same time or at some later time it will enqueue those newly-cleared weak references that are registered with reference queues.
(taken from the WeakReference
; Note the “at the same time or at some later time”)
In practice, the garbage collector hands over the discovered references to another thread which does the enqueuing asynchronously. Since an unspecified delay makes the order in which an application will retrieve the references from a queue undeterministic, it’s pointless to ask about an order here.
However, I suppose, you’re actually interested in the other “certain point in time”, when “the garbage collector determines that the reachability of the referent has changed to the value corresponding to the type of the reference” and will decide to clear the references atomically and make them eligible for enqueuing.
When there is a mixture of multiple differently typed reference objects, including a Finalizer
reference, but no strong reference, there are two possible scenarios:
Note that once finalization started, there is no Finalizer
reference anymore, but during finalization, new soft or weak reference might get created. So the resulting scenarios are the same as with the optimized handling of objects having a trivial finalize()
method. There can be a mixture of soft, weak, and phantom references, without a Finalizer
reference. When there is no remaining strong reference, we again have the two possible scenarios:
A phantom references are cleared in Java 9 or newer. In previous versions they are only enqueued without being cleared.