大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
一、一次标记
首先finalize方法是在垃圾回收时,用于确认该对象是否确认被回收的一个标记过程
。
确认一个对象真正被回收需要经历两次标记过程:
-
可达性分析没有引用,这是第一次标记
是否有必要执行finalize方法,如果对象没有重写finalize方法或者finalize方法已经被调用过了,那么finalize方法就是没有必要执行的,没有必要执行finalize方法的对象就会被直接回收。
如果对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中,并在稍后由一个由虚拟机创建、低优先级的finalizer线程去执行它。这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果一个对象的finalize()执行缓慢,极端情况下死循环,那么就会导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。 -
finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,
如果对象要在finalize()成功拯救自己——只需要重新与引用链上的任何一个对象建立关联即可,譬如把this关键字赋值给某个类的变量或者对象的成员变量,那么第二次标记时它将会被移出“即将回收”的集合;如果对象这时还没有逃脱,那么它就真正被回收了
。
/** * Finalizer方法逃避GC * 但是只能逃避一次 * create by chenxichao */
public class FinalizerEscapeGc {
public static FinalizerEscapeGc SAVE_HOOK = null;
public void isAlive(){
System.out.println("yes i am still alive :)");
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize method execute");
FinalizerEscapeGc.SAVE_HOOK = this;
}
public static void main(String[] args) throws Exception{
SAVE_HOOK = new FinalizerEscapeGc();
//对象第一次成功拯救自己
SAVE_HOOK = null;
System.gc();
//因为finalize方法的优先级很低,所以睡一下
Thread.sleep(500);
if(SAVE_HOOK != null){
SAVE_HOOK.isAlive();
}else{
System.out.println("no i am dead");
}
//第二次自救失败
SAVE_HOOK = null;
System.gc();
//因为finalize方法的优先级很低,所以睡一下
Thread.sleep(500);
if(SAVE_HOOK != null){
SAVE_HOOK.isAlive();
}else{
System.out.println("no i am dead");
}
}
}
二、 总结
- finalize方法不是一定会执行,只有在该方法被重写的时候才会执行 f
- inalize方法只会被执行一次
- 对象可以在finalize方法中获得自救,避免自己被垃圾回收,同样自救也只能一次
- 不推荐Java程序员调用该方法,因为finalize方法代价很大
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/191991.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...