java 可达性分析算法_垃圾回收:可达性分析算法、生存还是死亡(两次标记)

判断哪些内存需要回收

引用计数算法、可达性分析算法。引用计数算法优点实现简单,但是无法判断循环引用。

可达性分析算法:通过一系列的GC ROOTS作为起点,往下搜索,所走过的路径叫引用链。当一个对象没有引用链到GC ROOTS上,则可以回收。

1b46063e66e1a4b6af9339ddb2b34770.png

finalize 自救

finalize被执行,对象不一定被回收

一个对象宣布死亡,需要两次标记

第一次:没有与GC ROOTS相连接。finalize方法被覆盖并且没有调用过,则进入F-Queue队列。这个是在优先级低的finalizer线程执行,不保证等待线程结束。如果其中一个运行太久,其他对象的finalize会一直等待。

finalize是完成自救的最后机会。可以把this复制给GC ROOTS,避免第二次标记时被回收。不一定能救,因为优先级低

第二次:判断第一次标记的对象中,是否还是没有与GC ROOTS连接。如归是则回收,并且不会执行finalize(要么已经在第一次标记时执行,要么没有覆写)

不过finalize方法已经是Deprecated,由于可能导致性能,死锁和挂起等问题将会被移除。

例子

public class FinalizeEscapeGC {

public static FinalizeEscapeGC SAVE_HOOK = null;

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

SAVE_HOOK = new FinalizeEscapeGC();

SAVE_HOOK = null;

// 这两句保证进行垃圾回收标记, finalize能进行挽救自己

System.gc();

Thread.sleep(500);

if (SAVE_HOOK == null) {

System.out.println("i am dead");

} else {

// 这里被执行,成功挽救自己

System.out.println("i am still alive");

}

// 一样的的代码

SAVE_HOOK = null;

System.gc();

Thread.sleep(500);

if (SAVE_HOOK == null) {

// 这里被执行, 无法挽救,finalize只能执行一次

System.out.println("i am dead");

} else {

System.out.println("i am still alive");

}

}

@Override

protected void finalize() throws Throwable {

super.finalize();

SAVE_HOOK = this;

System.out.println("finalize execute");

}

}

输出:

finalize execute

i am still alive

i am dead

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值