Vla*_*nko 3 java garbage-collection jvm
据我了解,GC从一组初始对象(堆栈,静态对象)开始,然后递归遍历它,以建立可达对象图。然后,将这些对象占用的内存标记为已占用,并假定其余所有内存均已释放。
但是,如果此“空闲”内存包含具有finalize
方法的对象怎么办?GC必须调用它,但是我不知道它怎么能知道不再可访问的对象。
我想GC可以在所有“可完成的”对象存活时对其进行跟踪。如果是这样,拥有可终结化的对象是否会使垃圾回收即使在它们还活着的情况下也变得更加昂贵?
考虑参考API。
它提供了一些具有特殊语义的GC引用,即Weak,Soft和Phantom引用。public
对于需要最终确定的对象,仅存在另一种非特殊引用。
现在,当垃圾收集器遍历对象图并遇到这样的特殊引用对象时,它不会将通过此引用可访问的对象标记为强可访问性,而是将其标记为具有特殊语义。因此,如果一个对象仅是finalizer可访问的,则该引用将排队,以便一个(或其中一个)finalizer线程可以轮询队列并执行该finalize()
方法(不是垃圾回收器本身调用此方法)。
换句话说,垃圾收集器从不处理完全不可达的对象。要将特殊语义应用于可到达性,引用对象必须是可到达的,因此可以通过该引用来达到引用对象。在finalizer-reachability Finalizer.register
的情况下,Finalizer
在创建对象并依次创建的实例,的子类FinalReference
并在其构造函数中创建时调用,它将调用add()
将引用插入到全局链接列表中的方法。因此,所有这些FinalReference
实例都可以通过该列表访问,直到实际完成。
由于FinalReference
将在对象的实例化时立即创建该对象,因此,如果其类声明了一个非平凡的finalize()
方法,则由于具有终结处理要求,即使该对象尚未收集,也已经存在一些开销。
另一个问题是,由终结器线程处理的对象可以通过该线程访问,甚至可能转义,这取决于finalize()
方法的作用。但是下一次,该对象将变得不可访问,特殊引用对象不再存在,因此可以像对待其他任何不可访问的对象一样对待它。
如果内存非常低,并且必须更早执行下一个垃圾回收才能最终回收该对象,那么这只会是性能问题。但这在参考实现(也称为“ HotSpot”或“ OpenJDK”)中不会发生。实际上,OutOfMemoryError
终结器队列中可能有一段时间未决对象,其处理可能会使更多的内存可回收。不能保证最终运行的速度足以满足您的目的。这就是为什么您不应该依赖它的原因。
归档时间: |
|
查看次数: |
1053 次 |
最近记录: |