写在前面:2020年面试必备的Java后端进阶面试题总结了一份温习指南在Github上,内容详细,图文并茂,有需要学习的同伙可以Star一下!
GitHub地址:https://github.com/abel-max/Java-Study-Note/tree/master

判断工具是否已死

判断工具是否已死就是找出哪些工具是已经死掉的,以后不会再用到的,就像地上有废纸、饮料瓶和百元大钞,扫地前要先判断出地上废纸和饮料瓶是垃圾,百元大钞不是垃圾。判断工具是否已死有引用计数算法和可达性剖析算法。

1.引用计数算法

给每一个工具添加一个引用计数器,每当有一个地方引用它时,计数器值加 1;每当有一个地方不再引用它时,计数器值减 1,这样只要计数器的值不为 0,就说明另有地方引用它,它就不是无用的工具。如下图,工具 2 有 1 个引用,它的引用计数器值为 1,工具 1有两个地方引用,它的引用计数器值为 2 。

这种方式看起来异常简朴,但现在许多主流的虚拟机都没有选用这种算法来治理内存,缘故原由就是当某些工具之间相互引用时,无法判断出这些工具是否已死,如下图,工具 1 和工具 2 都没有被堆外的变量引用,而是被对方相互引用,这时他们虽然没有用处了,然则引用计数器的值仍然是 1,无法判断他们是死工具,垃圾接纳器也就无法接纳。

2.可达性剖析算法

领会可达性剖析算法之前先领会一个观点——GC Roots,垃圾 *** 的起点,可以作为 GC Roots 的有虚拟机栈中内陆变量表中引用的工具、方式区中静态属性引用的工具、方式区中常量引用的工具、内陆方式栈中 JNI(Native 方式)引用的工具。

当一个工具到 GC Roots 没有任何引用链相连(GC Roots 到这个工具不可达)时,就说明此工具是不可用的,是死工具。

如下图:object1、object2、object3、object4 和 GC Roots 之间有可达路径,这些工具不会被接纳,但 object5、object6、object7 到 GC Roots 之间没有可达路径,这些工具就被判了死刑。

上面被判了死刑的工具(object5、object6、object7)并不是必死无疑,另有拯救的余地。举行可达性剖析后工具和 GC Roots 之间没有引用链相连时,工具将会被举行一次符号,接着会判断若是工具没有笼罩 Object的finalize() 方式或者 finalize() 方式已经被虚拟机挪用过,那么它们就会被行刑(消灭);若是工具笼罩了 finalize() 方式且还没有被挪用,则会执行 finalize() 方式中的内容,所以在 finalize() 方式中若是重新与 GC Roots 引用链上的工具关联就可以拯救自己,然则一样平常不建议这么做,周志明先生也建议人人完全可以忘记这个方式~

3.方式区接纳

上面说的都是对堆内存中工具的判断,方式区中主要接纳的是废弃的常量和无用的类。

判断常量是否废弃可以判断是否有地方引用这个常量,若是没有引用则为废弃的常量。

判断类是否废弃需要同时知足如下条件:

  • 该类所有的实例已经被接纳(堆中不存在任何该类的实例)。

  • 加载该类的 ClassLoader 已经被接纳。

  • 该类对应的 java.lang.Class 工具在任何地方没有被引用(无法通过反射接见该类的方式)。