垃圾回收器中finalize方法的执行过程

  • Post author:
  • Post category:其他




大致描述一下finalize流程

当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。



具体的finalize流程:

对象可由两种状态,涉及到两类状态空间,一是终结状态空间 F = {unfinalized, finalizable, finalized};二是可达状态空间 R = {reachable, finalizer-reachable, unreachable}。各状态含义如下:

• unfinalized: 新建对象会先进入此状态,GC并未准备执行其finalize方法,因为该对象是可达的

• finalizable: 表示GC可对该对象执行finalize方法,GC已检测到该对象不可达。正如前面所述,GC通过F-Queue队列和一专用线程完成finalize的执行

• finalized: 表示GC已经对该对象执行过finalize方法

• reachable: 表示GC Roots引用可达

• finalizer-reachable(f-reachable):表示不是reachable,但可通过某个finalizable对象可达

• unreachable:对象不可通过上面两种途径可达

状态变迁图:

变迁说明:


1. 新建对象首先处于[reachable, unfinalized]状态(存在引用)

2. 随着程序的运行,一些引用关系会消失,导致状态变迁,从reachable状态变迁到f-reachable或unreachable状态(未引用,或引用某个finalizable对象)

3. 若JVM检测到处于unfinalized状态的对象变成f-reachable或unreachable,JVM会将其标记为finalizable状态。若对象原处于[unreachable, unfinalized]状态,则同时将其标记为f-reachable。(刚创建出来的对象引用某个finalizable对象)

4. 在某个时刻,JVM取出某个finalizable对象,将其标记为finalized并在某个线程中执行其finalize方法。由于是在活动线程中引用了该对象,该对象将变迁到(reachable, finalized)状态。该动作将影响某些其他对象从f-reachable状态重新回到reachable状态(因为该finalizable对象已经复活,所以引用有效)

5. 处于finalizable状态的对象不能同时是unreahable的(这是因为unreahable状态要么存在于刚创建出来的方法的变迁结果,要么存在于已经为finalized状态的对象),

6. 程序员手动调用finalize方法并不会影响到上述内部标记的变化,因此JVM只会至多调用finalize一次,即使该对象“复活”也是如此。程序员手动调用多少次不影响JVM的行为

7. 若JVM检测到finalized状态的对象变成unreachable,回收其内存

8. 若对象并未覆盖finalize方法,JVM会进行优化,直接回收对象



版权声明:本文为qq_41012446原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。