java 对象被回收的例子_Java对象的"后事处理"——垃圾回收(二)

1 先谈Finalize()

finalize()能做的所有工作,使用try-finally或者其他方式都可以做得更好、更及时,所以笔者建议大家完全可以忘掉Java语言中有这个方法的存在。

——《深入理解JVM》

finalize()方法确实可以实现一次对象的自救,但是其不确定性和昂贵的运行代价都表明这个方法的使用需要十分的慎重。那么finalize()在什么时期起作用又是如何实现对象的自救的呢?首先我们要理解虚拟机在扫描到死亡对象的时候并不是直接回收的,而是进行一次标记并且筛选,筛选的条件就是其对象的finalize方法是否有必要执行。如果当前对象没有重写finalize方法或者已经调用过一次finalize方法,那么则视为没有必要执行,此时便失去自救的机会,放入"即将回收"集合中。

否则的话,则将对象放入一个叫F-Queue的队列中,稍后虚拟机将一个个的执行队列中对象的finalize方法(就是在此处对象可以在finalize方法中将自身关联到引用链,从而暂时逃脱被回收的命运),需要注意的是虚拟机保证执行但不保证执行完finalize方法,原因是如果finalize方法执行时间过长或者陷入死循环,则可能让系统奔溃。全部执行之后,虚拟机将对队列的对象重新标记一次,如果还不在引用链中则GG,否则将其移出"即将回收"集合。下面例子参考《深入理解JVM》实现自救并且验证只能自救一次的过程。

public classTestForGc {/**定义一个根节点的静态变量*/

public staticTestForGc INSTANCE;/*** 重写finalize方法,让其被标记为有必要执行并且加入F-Q

*

*@throwsThrowable*/@Overrideprotected void finalize() throwsThrowable {super.finalize();

System.err.println("finalize method in TestForGc Class invoked!");//将自身关联到根节点中,实现自救

INSTANCE = this;

}public static void main(String[] args) throwsInterruptedException {

INSTANCE= newTestForGc();

INSTANCE= null;

System.gc();//睡眠1S,保证F-Q中的方法执行完毕

TimeUnit.SECONDS.sleep(1);if(Objects.nonNull(INSTANCE)) {

System.out.println("i successfully save myself by finalize method!");

}else{

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

}/** 下面验证finalize方法只能调用一次

* 几乎完全一样的代码,却是不同的结局*/INSTANCE= null;

System.gc();//睡眠

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值