static变量会被垃圾回收吗_当对象不可达一定会被JVM回收吗?

Java中的static变量不一定会被垃圾回收,因为JVM的垃圾回收算法考虑到对象可能重新变得可达。当对象经过可达性分析后不可达,会先进行标记并筛选,如果对象覆盖了finalize()方法,会被放入F-Queue队列。虚拟机通过Finalizer线程执行finalize(),若在此期间对象自救成功,即恢复可达性,将不会被回收;否则,将在第二次标记后被真正回收。代码示例展示了自救过程:第一次自救成功,第二次因finalize()仅被调用一次而失败。
摘要由CSDN通过智能技术生成
99602c893debe04804ddc46896e9e22d.png

看到标题这如果是判断题那简直就是送分儿题,答案很明显:不一定。

如果是问答题,那还得解释一下为啥不一定,不然交卷也不可能是满分或者高分,这在面试的时候一样如此。

那因为啥不一定被JVM垃圾回收器回收呢?

这是因为JVM的垃圾回收算法设计的宽容性,好不容易生产的对象咋能随便就收了,万一又可达了呢。

何时一定被回收?

先看一段代码:

public class LiveInGC { private static LiveInGC liveInGC = null; private void isAlive(){ System.out.println("我还活着"); } @Override protected void finalize() throws Throwable { super.finalize(); liveInGC = this; } public static void main(String[] args) throws InterruptedException { liveInGC = new LiveInGC(); saveMyself();//第一次自救 saveMyself();//第二次自救 } private static void saveMyself() throws InterruptedException { //置空等待垃圾回收 liveInGC = null; System.gc(); //finalize方法优先级比较低等待一下让liveInGC自救 Thread.sleep(1000); if (liveInGC == null){ System.out.println("我被回收了"); }else { liveInGC.isAlive(); } }}

代码运行结果如下:

6b76ca5a14b2b09696110ab9335f6205.png

结果显示第一次自救成功,第二次失败。

以上简单的代码描述了垃圾回收的一个基本机制:

1.在进行垃圾回收过程中发现如果一个对象在经过可达性分析后发现其不可达则对该对象进行第一次标记和筛选。

标记的是该对象处于第一次被判断不可达准备回收状态。

筛选的是是否执行finalize()方法:

没必要执行:对象没有覆盖finalize()方法or虚拟机已经调用过

需要执行:覆盖了finalize()方法(例如以上代码)

2.筛选判定需要执行finalize方法

1)开始回收计划,将对象放置在一个叫做F-Queue队列

2)虚拟机自动建立一个Finalizer线程默默处理队列中需要回收的对象,执行finalize()方法

3)GC此后对F-Queue中的对象进行第二次标记,标记的时候如果对象此时在覆盖的finalize()方法中将this对象指向了自己那么它将被移出“即将回收”的集合。如果没有,那么它就会被回收

4)以上代码中第一次自救成功就是在finalize()方法中又给自己的成员变量,而第二次失败则是因为对象的finalize()方法最多被系统自动调用一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值