On Tue, Nov 29, 2011 at 7:12 AM, Chuck Remes <cremes.devlist / mac.com> wrote:
> I have a project that uses a finalizer to deallocate some native memory (allocated via FFI). I see the same behavior as you describe on MRI. On JRuby and Rubinius the finalizer is called "closer in time" to when the object is reaped but I don't know for certain that it is happening in the same cycle as the GC. For all I know it's pushing the finalizer reference onto another queue somewhere and getting to it during its idle time.

That is, in fact, what Hotspot does. If you get a thread dump from a
running OpenJDK JVM, you'll see something like this:

"Finalizer" daemon prio=5 tid=0x000000010086f800 nid=0x106c80000 in
Object.wait() [0x0000000106c7f000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x00000007f5965e70> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
	- locked <0x00000007f5965e70> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

It waits for finalizable object references to be pushed onto its queue
and then runs their finalizers.

- Charlie