问题描述
主要问题在主题中,但让我展示一下我对 Java 中完成过程的看法,以便我可以问你更多问题.
The main question is in the topic but let me show my vision of finalization proccess in Java so that I can ask you a little more.
gc 通过标记所有活动对象开始垃圾收集.当所有可达对象都被标记为活动"时.所有其他对象都无法访问.下一步是检查每个无法到达的对象,并确定它是否可以立即被清扫,或者应该首先完成.如果对象的 finalize 方法有一个主体,那么 gc 会考虑下一个方法,那么这个对象是可终结的并且应该被终结;如果对象的 finalize 方法有一个空主体(受保护的 void finalize(){ }),那么它是不可终结的,现在可以被 gc 清除.(我说得对吗?)
所有可终结的对象都将放在同一个队列中,以便稍后一一终结.据我了解,一个可终结的对象在等待轮到它最终确定时可能会花费大量时间被放入队列中.这可能会发生,因为通常只有一个名为 Finalizer 的线程从队列中获取对象并调用它们的 finalize 方法,并且当我们在某个对象的 finalize 方法中进行一些耗时的操作时,队列中的其他对象将等待很长时间才能完成.好吧,当一个对象已经完成时,它会被标记为 FINALIZED 并从队列中删除.在下一次垃圾收集过程中,收集器将看到该对象(再次)无法访问并且具有非空的 finalize 方法(再次)因此该对象应该被放入队列中(再次) - 但它赢了'不是因为收集器以某种方式看到这个对象被标记为 FINALIZED. (这是我的主要问题:这个对象以什么方式被标记为 FINALIZED,收集器如何知道这个对象不应该再次敲定?)
Well the gc starts garbage collection by marking all live objects. When all reachable objects are marked as "live". All other objects are unreachable. The next step is to check every unreachable object and determine whether it can be sweeped right now or it should be finalized at first. The gc thinks the next way if the object's finalize method has a body then this object is finalizable and should be finalized; if the object's finalize method has an empty body (protected void finalize(){ }) then it is not finalizable and can be sweeped by gc right now. (Am I right about it?)
All finalizable objects will be put in the same queue to be finalized later one by one. As I understand a finalizable object can spend a lot of time being placed to the queue while waiting for its turn to be finalized. This can happen because normally only one thread called Finalizer are taking objects from the queue and call their finalize method, and when we have some time consuming operations in some object's finalize method the other objects in the queue will be waiting pretty long to be finalized. Well when an object has been finalized it is marked as FINALIZED and removed from the queue. During the next garbage collection process the collector will see that this object is unreachable (again) and has non-empty finalize method (again) so this object should be put in the queue (again) - but it won't because the collector somehow see that this object was marked as FINALIZED. (This is my main question: in what way this object was marked as FINALIZED, how the collector knows that this object shouldn't be finalized again?)
推荐答案
只要我们说的是HotSpot JVM ...
As long as we are talking about HotSpot JVM ...
对象本身未标记为已完成.
Object itself IS NOT marked as finalized.
每次创建新的 finalize 对象时,JVM 都会创建一个额外的对象 FinalizerRef(这有点类似于 Weak/Soft/Phantom 引用).
Each time when you create new finalize object, JVM creates an extra object FinalizerRef (which is somewhat similar with Weak/Soft/Phantom references).
一旦您的对象通过强引用被证明不可访问,对该对象的特殊引用就会被处理.您的对象的 FinalizerRef 将被添加到终结器队列(这是链表,与其他引用类型相同).
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).
当终结器线程从队列中使用 FinalizerRef 时,它会将其指向对象的空指针设为空(尽管线程将保持对对象的强引用直到终结器完成).
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).
一旦 FinalizerRef 无效,对象就不能再进入终结器队列了.
Once FinalizerRef is nullified, object cannot get to finalizer queue any more.
顺便说一句
您可以使用 -XX:+PrintReferenceGC
(查看更多 GC 诊断 JVM 选项)
这篇关于在 Java 中如何将对象标记为 finalized(以便第二次不会调用 finalize 方法)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!