How is an object marked as finalized in Java (so that the finalize method wouldn't be called the second time)?

最后都变了- 提交于 2019-11-28 20:56:35

As long as we are talking about HotSpot JVM ...

Object itself IS NOT marked as finalized.

Each time when you create new finalize object, JVM creates an extra object FinalizerRef (which is somewhat similar with Weak/Soft/Phantom references).

Once your object is proven to unreachable with strong references special references to this object are processed. FinalizerRef for you object will be added to finalizer queue (which is linked list, same as with other reference types).

When finalizer thread consumes FinalizerRef from queue it would null its null pointer to object (though thread will keep strong reference to object until finalizer is finished).

Once FinalizerRef is nullified, object cannot get to finalizer queue any more.

BTW

You can see preference processing times (and number of references) in GC logs with -XX:+PrintReferenceGC (see more GC diagnostic JVM options)

The JVM stores meta data in the object header. Any object with a sub-classes finalize() is called, even if empty. Placing in the queue doesn't take long, but it can wait in the queue for a long time.

I don't know how exactly the real, implemented finalizing process works, but if i had to do it, i'd do it this way - store a tri-state flag in the object metadata that tells GC if the object just stopped being in use, needs the finalizer to be run, or may be removed. You'll probably have to check the java source for details but this should be the overall pattern:

(in new)

object.metadata.is_finalized=NEEDS_FINALIZE;

(in gc)

while ((object=findUnreachableObject())!=null) {
    if (object.metadata.is_finalized==NEEDS_FINALIZE) {
        if (hasNonNullBody(object.finalize)) {
            Finalizer.addForProcessing(object);
            object.metadata.is_finalized=IN_FINALIZER_QUEUE;
        } else {
            object.metadata.is_finalized=REMOVE_NOW;
        }
    }
    if (object.metadata.is_finalized==REMOVE_NOW) {
        // destroy the object and free the memory
    }
}

(in Finalizer)

while ((object=getObjectForProcessing)!=null) {
    object.finalize();
    object.metadata.is_finalized=REMOVE_NOW;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!