写在前面:2020年面试必备的Java后端进阶面试题总结了一份复习指南在Github上,内容详细,图文并茂,有须要学习的朋友能够Star一下!
GitHub地址:https://github.com/abel-max/Java-Study-Note/tree/masterjava
判断对象是否已死就是找出哪些对象是已经死掉的,之后不会再用到的,就像地上有废纸、饮料瓶和百元大钞,扫地前要先判断出地上废纸和饮料瓶是垃圾,百元大钞不是垃圾。判断对象是否已死有引用计数算法和可达性分析算法。git
1.引用计数算法github
给每个对象添加一个引用计数器,每当有一个地方引用它时,计数器值加 1;每当有一个地方再也不引用它时,计数器值减 1,这样只要计数器的值不为 0,就说明还有地方引用它,它就不是无用的对象。以下图,对象 2 有 1 个引用,它的引用计数器值为 1,对象 1有两个地方引用,它的引用计数器值为 2 。面试
这种方法看起来很是简单,但目前许多主流的虚拟机都没有选用这种算法来管理内存,缘由就是当某些对象之间互相引用时,没法判断出这些对象是否已死,以下图,对象 1 和对象 2 都没有被堆外的变量引用,而是被对方互相引用,这时他们虽然没有用处了,可是引用计数器的值仍然是 1,没法判断他们是死对象,垃圾回收器也就没法回收。算法
2.可达性分析算法后端
了解可达性分析算法以前先了解一个概念——GC Roots,垃圾收集的起点,能够做为 GC Roots 的有虚拟机栈中本地变量表中引用的对象、方法区中静态属性引用的对象、方法区中常量引用的对象、本地方法栈中 JNI(Native 方法)引用的对象。ide
当一个对象到 GC Roots 没有任何引用链相连(GC Roots 到这个对象不可达)时,就说明此对象是不可用的,是死对象。学习
以下图:object一、object二、object三、object4 和 GC Roots 之间有可达路径,这些对象不会被回收,但 object五、object六、object7 到 GC Roots 之间没有可达路径,这些对象就被判了死刑。对象
上面被判了死刑的对象(object五、object六、object7)并非必死无疑,还有挽救的余地。进行可达性分析后对象和 GC Roots 之间没有引用链相连时,对象将会被进行一次标记,接着会判断若是对象没有覆盖 Object的finalize() 方法或者 finalize() 方法已经被虚拟机调用过,那么它们就会被行刑(清除);若是对象覆盖了 finalize() 方法且尚未被调用,则会执行 finalize() 方法中的内容,因此在 finalize() 方法中若是从新与 GC Roots 引用链上的对象关联就能够拯救本身,可是通常不建议这么作,周志明老师也建议你们彻底能够忘掉这个方法~内存
3.方法区回收
上面说的都是对堆内存中对象的判断,方法区中主要回收的是废弃的常量和无用的类。
判断常量是否废弃能够判断是否有地方引用这个常量,若是没有引用则为废弃的常量。
判断类是否废弃须要同时知足以下条件:
该类全部的实例已经被回收(堆中不存在任何该类的实例)。
加载该类的 ClassLoader 已经被回收。