看到标题这如果是判断题那简直就是送分儿题,答案很明显:不一定。
如果是问答题,那还得解释一下为啥不一定,不然交卷也不可能是满分或者高分,这在面试的时候一样如此。
那因为啥不一定被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(); } }}
代码运行结果如下:
结果显示第一次自救成功,第二次失败。
以上简单的代码描述了垃圾回收的一个基本机制:
1.在进行垃圾回收过程中发现如果一个对象在经过可达性分析后发现其不可达则对该对象进行第一次标记和筛选。
标记的是该对象处于第一次被判断不可达准备回收状态。
筛选的是是否执行finalize()方法:
没必要执行:对象没有覆盖finalize()方法or虚拟机已经调用过
需要执行:覆盖了finalize()方法(例如以上代码)
2.筛选判定需要执行finalize方法
1)开始回收计划,将对象放置在一个叫做F-Queue队列
2)虚拟机自动建立一个Finalizer线程默默处理队列中需要回收的对象,执行finalize()方法
3)GC此后对F-Queue中的对象进行第二次标记,标记的时候如果对象此时在覆盖的finalize()方法中将this对象指向了自己那么它将被移出“即将回收”的集合。如果没有,那么它就会被回收。
4)以上代码中第一次自救成功就是在finalize()方法中又给自己的成员变量,而第二次失败则是因为对象的finalize()方法最多被系统自动调用一次。