垃圾收集与对象生命拯救

上一篇 / 下一篇  2012-11-16 11:00:41 / 个人分类:Java

&VJ;Tx5E)?,vdq.M0  Java是根据根搜索算法来判断对象是否存活的。基本思路是:通过一系列名为“GC Roots”的对象作为起点,向下搜索锁走过的路径(称为引用链),当一个对象与GC Roots之间的连接是断开的,也就是对象与GC Roots之间是不可达的时候,该对象就是“不可用”的,注意只是不可用的而不是该对象已经死了。这时候该对象只是暂时处于死刑的“缓刑”阶段。既然是缓 刑,就可以补救回来。51Testing软件测试网|WM$N+q3\.c @IY8L

51Testing软件测试网1q ~|3UH

  其实要真正地宣告一个对象是否死亡至少要经历两次标记过程51Testing软件测试网;X-P/K)PGB

5}/Q7W,J-A9pW0  A、处于“缓刑”状态的对象,会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖此方法或者finalize()的方法已经被虚拟机调用过,在这两种情况都是为“没有必要执行”finalize()方法

$BTQ,J r~*A0

C oj [I0k\q0  B、Finalize()方法是对象逃离死亡命运的最后一次机会,稍后GC会对对象进行第二次小规模的标记,如果对象要在该方法中拯救自己 ------只需要重新与GC Roots引用链上的任何一个对象建立关联即可。譬如把自己(this关键字)赋值给某个类的变量或对象的成员变量,那在第二次标记时它就会被移除出“即 将回收”的集合,如果这个时候该对象还没有逃脱,那么该对象就真的里死亡不远了51Testing软件测试网/Uatj0m"C7B cs

:Q0D f6J2Nc0  代码说明如下

%W+{5q0R1NN&G0 51Testing软件测试网&G6i.Hpe$X5mHN

d?Z/{4}&lW[,S0

Mv9pL%w B&r,b']0/*
0Oa3w&SVl,k&S0 * To change this template, choose Tools | Templates
(}1MI j(LU.H0 * and open the template in the editor.51Testing软件测试网5M$Vzz*J6f)S(dm
 */51Testing软件测试网k"DaFF t!f:I]&`
package x;

(ss,T W/j;y7[dH0

F5m H6D]OqH K6N&~!s0/**
rm%t)[0s8HU7F0 *51Testing软件测试网cu6r'I~sQ$zk#Qm
 * @author Arthur
e0kU2B)gq;yH0 */
y:]#g O\6nRiv0public class FinalizeEscapeGc {

6^:VXyb~e0

^ @+_;}Zv0    private int count = 0;51Testing软件测试网6y@7DU&sCDH
    private static FinalizeEscapeGc fec = new FinalizeEscapeGc();
51Testing软件测试网cB"I+_ N c#P`~

51Testing软件测试网M V7{j7Rn|!w

    public FinalizeEscapeGc() {51Testing软件测试网,Zl@+CosL
    }
51Testing软件测试网G;b{AA

51Testing软件测试网%X7|VS;o8I

    public static void main(String[] args) throws InterruptedException {

} mN{(}ZiB+VUp ^0 51Testing软件测试网-z&y"CU[,j$ep?8d

        //对象第一次成功拯救自己51Testing软件测试网?l%AEq#ciaC
        fec = null;
-e1M,X{#j5d-lPU0        System.gc();51Testing软件测试网/Wai1~#uPW:|u
        ////显然输出为null
u U,m0P [,_#G*Q0        System.out.println(fec);51Testing软件测试网`.t+`1oO3}E
        //因为finalize优先级很低,暂停一秒,以等待它51Testing软件测试网 k0Mh7p,Vn_At
        Thread.sleep(1000);51Testing软件测试网-d|9WP&t*T/n&qa
        //打印x.FinalizeEscapeGc@c17164,说明成功拯救
W)fb0x@?.C E|$] h4c~0        System.out.println(fec);51Testing软件测试网3xT/Sm+M
    
'bl[&\7jq"p0        51Testing软件测试网 [+g*Wg+}/]\fO
        //第二次次拯救失败51Testing软件测试网M5xPrpR$Vr&W
        fec = null;
UW"Fsi0        //显然输出为null51Testing软件测试网I dm\Eg'CF R
        System.out.println(fec);51Testing软件测试网0s1?#J,\S'v6`I
      
$a G:d$B,pt n.@#k;`0        System.gc();
S#j.oP1fR0        //因为finalize优先级很低,暂停一秒,以等待它
4B;ku,Z N1K6Il0        Thread.sleep(1000);
TI5k&}3M+r0CX0        //输出为null51Testing软件测试网$p6y%w.i4K+L:BK"\A*m
        System.out.println(fec);
M5UU5}rIY0       
51Testing软件测试网B7H-G o,\&E v*J"I

9Y:G|,IPu [ wXN0    }

u_B\4W:I4zk0 51Testing软件测试网0H#g rM'J

    @Override51Testing软件测试网\,l'_"Oj7~ AN*{!o
    public void finalize() throws Throwable {51Testing软件测试网&F-E0Mo`b
        super.finalize();
#XK\Z?y}dc0        System.out.println("执行finalize方法");
;IT+M n4N!P}0fB&[0        fec = this;
51Testing软件测试网2ov-N^\9|

51Testing软件测试网V]E(p2D*A G

    }

vx9OQ]~ oW0 51Testing软件测试网$HiX$QCr:j

    public int getCount() {
Mp,L{"g!f%mG0        return count;51Testing软件测试网]6sza-x8Pq
    }
0H+@G,y%k1Y$l;T s3B I0}

dap|5R@V4`$_0
51Testing软件测试网 cG._5sm9o%f

  注意finalize方法是被GC收集器触发,如果注释掉System.gc()注释掉的话,是不会执行finalize方法的。51Testing软件测试网o#Ow%K L h-qGK!vF


TAG:

 

评分:0

我来说两句

Open Toolbar