[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-hotspot-gc-use
Subject:    Re: About the finalization queue and reference queue
From:       Bernd Eckenfels <ecki () zusammenkunft ! net>
Date:       2016-10-11 21:25:51
Message-ID: 20161011232551.00005ac8.ecki () zusammenkunft ! net
[Download RAW message or body]

Hello,

Am Tue, 11 Oct 2016 20:55:54 +0000
schrieb Jun Zhuang <jun.zhuang@hobsons.com>:

> *         A Finalizer instance is created for every finalizeable
> object

Yes, the java.lang.ref.Finalizer.Finalizer(Object) constructor will put
the referent in the referent` field of Finalizer (declared in parent
class Referent) and then link this instance with add() method at the
head of the list. The head is kept alive by Finalizer#unfinalized
(which is static). This constructor is called (via
Finalizer#register(Object)) by the JVM when it creates a new
finalizeable object.

> *         All the Finalizer instances are linked together using a
> double linked list

Yes, they dont use a LikedList class but implement the next/prev fields
themself (so this needs no additional instances).

> *         All the Finalizer instances are tracked by the
> java.lang.ref.Finalizer class. Or is it only the first one by the
> unfinalized field?

The head of the linked list is referenced by `unfinalized field. It
points to a Finalizer instance, which points which the next field to the
next Finalized and so on (and each of them has a referee).

> What I am still not clear are:
> 
> 1.       Is there a finalization queue at all? If so, what does it do?

There is a ReferenceQueue in the static field queue. This queue is
given to all Finalize instances (the field "queue" in Reference holds
thatuntil needed). The objets are enqueued to this queue by the GC. The
Finalizer thread reads them from this queue and knows "this one is now
not reachable anymore" and does its work (and removes it from the queue
and also remove the Finalize wrapper from its linked list).

> 2.       What goes into the ReferenceQueue? The finalizeable objects?

References go to the ReferenceQueue, the wrapper Finalizer instance is
also a (Final)Reference. In case of FinalReference the queue can look
at the Finalize#get() to get the referent and call finalize() on this.

Same mechanism asdone for allother Reference types (with the exception
of phantom references which do not allow this get).

The Finalize class is a real beast:

- instances are a Reference wrapping the finalizeable objects
- instances form a double linked list of all Finalize instances
- the class itself holds the head of the list and the queue alive in
  statics 
- the FinalizerThread (which removes Finalizer instances from the
  ReferenceQueue and invokes the finalizer method on it (once) is a
  inner class: Finalizer$FinalizerThread
- the static initializer of Finalizer actually starts the
  FinalizerThread (as a daemon with MAX-2 prio).
- the static field lock in Finalizer is used to synchronize the daemon
  thread with secondary finalizer threads (from runAllFinalizers() on
  shutdown or Runtime.runFinalizazion())

Lots of the finalization logic is done in Java, only the register() and
Reference discovery is done by the runtime/gc.

You can see that here, note especially the "Invoked by" comments (and
parents):

http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/2bf254421854/src/java.base/share/classes/java/lang/ref/Finalizer.java


Bernd
_______________________________________________
hotspot-gc-use mailing list
hotspot-gc-use@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic