关于java:面试官超级喜欢问的垃圾回收算法

2次阅读

共计 2179 个字符,预计需要花费 6 分钟才能阅读完成。

前言

通过前段时间一面的通过,阿巴阿巴被邀请进入二面,这次她与遇到的面试官将持续尴尬她,要问她对于 GC 算法的问题

回家等告诉

面试官: 你对 JVM 的垃圾回收理解吗?

阿巴阿巴: 嗯嗯,理解一些。

面试官: 那么 JVM 是如何判断一个对象是垃圾呢?

阿巴阿巴: 如同有一个可达性分析法。

阿巴阿巴: 就是对象可达会断定为活对象,而后不可达的就当作“垃圾”。

面试官: 嗯 …. 讲一下你理解的垃圾回收算法吧。

阿巴阿巴:

标记分明算法

标记整顿算法

复制算法

分代收集算法

面试官: 嗯 …. 那你对这些算法理解吗?

阿巴阿巴: 嗯 …. 不太理解 …

面试官: 行,明天先面到这里,你这边先回去等告诉吧😈

阿巴阿巴: 好的。

很遗憾,您未能通过面试,您的简历已退出公司人才库,期待下次相遇 ……

当场拿 Offer

面试官: 你对 JVM 的垃圾回收理解吗?

阿巴阿巴: 嗯嗯,理解一些。

面试官: 那么 JVM 是如何判断一个对象是垃圾呢?

阿巴阿巴: 有两种办法,一种是援用计数法,另一种是可达性分析法。

阿巴阿巴: 援用计数法就是给对象一个援用计数器,每当有援用引向该对象时,援用计数器就加一,每当有援用断开的时候,援用计数器就减一,这样当援用计数起为零时,那么就认为这个对象曾经没有用了,也就是所谓的垃圾,然而这种形式有个很大的弊病,对于循环援用无奈解决。

阿巴阿巴: 循环援用的对象内部援用存在的状况,这种状况看似没啥问题,然而当咱们把办法区的援用断开时,问题久裸露进去了。


阿巴阿巴: 循环援用的对象内部援用断开的状况。

阿巴阿巴: 下面这种援用断开的状况,显然对象 A 和对象 B 曾经没有内部援用来援用它们,它们曾经成为了垃圾,而援用计数器因为它们互相援用(循环援用),其值都为 1,导致无奈被回收,这个弊病导致援用计数法理论并没有在 JVM 中所应用。

阿巴阿巴: 可达性分析法就是通过 GC Roots 的对象,以它为根往下搜寻,这条被搜寻的门路称为“援用链”,当一个对象不被任何 GC Roots 的援用链所链接,那么久断定这个对象曾经“死了”,咱们个别称这个对象“不可达”。

面试官: 你刚有提到 GC Roots,那你晓得哪些对象能够作为 GC Roots 的对象吗?

阿巴阿巴: 嗯嗯理解,次要有以下四类对象能够作为 GC Roots 的对象。

虚拟机栈中援用的对象

办法区中动态属性援用的对象

办法区中常量援用的对象

本地办法栈中援用的对象

阿巴阿巴: 上面这张图能够直观的看出它们的关系。

阿巴阿巴: 能够看出,只有被援用链链上的对象能力被断定为“存活”,而不在援用链上的对象则被断定为“死亡”,也将作为垃圾被回收。

面试官: 讲的很不错,那垃圾回收除了回收堆中的对象外,办法区中会有垃圾被回收吗?

阿巴阿巴: 办法区中也是有垃圾回收的,办法区中次要回收废除了的常量和无用的类。

面试官: 嗯 …. 讲一下你理解的垃圾回收算法吧。

阿巴阿巴: 垃圾回收算法次要有以下四类。

标记分明算法

标记整顿算法

复制算法

分代收集算法

阿巴阿巴: 标记分明算法,是分为 2 个阶段的,第一个阶段进行“标记”,第二个阶段进行“革除”,先标记出所有要革除的对象,也就是灰色局部,而后进行回收。

阿巴阿巴: 采纳标记分明算法对堆进行垃圾清理后,产生了很多空间碎片,这些空间碎片使新对象的内存调配造成艰难,不仅如此,标记革除算法在标记阶段和革除阶段的效率都不太高。

阿巴阿巴: 标记整顿算法孕育而生,解决了过多内存碎片的问题。

阿巴阿巴: 为了解决效率的问题,复制算法也呈现了,即把一块内存分成大小相等的 2 块,每次应用的时候只应用其中的一块,当一块没存应用完的时候,把这块内存中存活的对象转移到另一块内存中,而后将这块内存中的对象全副清空。

阿巴阿巴: 复制算法实现简略、不便且效率很高,也不须要思考内存碎片的问题,然而要将内存放大为原来的一半,这代价无疑很高。

阿巴阿巴: 而且新生代的对象大多数都是朝生夕死的,依照 1:1 的空间比例来应用复制算法,将极大的影响了内存的性能。

阿巴阿巴: 分代算法行将堆区进行划分,而后依据不同区域的状况来实用相应的垃圾回收算法。

阿巴阿巴: 下图是对新生代的细化,新生代分成 Eden 区和 survivor 区,其中 survivor 区又分为 (s0 和 s1) 俩个区域,它们的比例如图所示为 8 : 1 : 1。新对象优先会在 Eden 区进行调配, 标记革除算法在这里不实用,因为碎片太多,如果没有间断的足够空间来调配给对象,又会持续触发垃圾回收,对性能影响比拟大。

阿巴阿巴: 对于传统的 GC 来说,都无奈防止 GC 过程中带来的“STOP-THE-WORLD”,咱们个别简称 STW,STW 对系统性能的影响很大,那么如何打消 STW 或者缩小 STW 的工夫显得尤为重要,其实分代算法并非是一种具体的算法,和后面的标记革除、标记整顿算法、复制算法不同的是,分代算法只是对对堆得一个划分,而后在不同区域应用不同的算法,从而将 STW 的工夫细分到各个区域,使得 STW 工夫不会继续很长一段时间,来达到进步零碎性能的目标。

面试官: 讲的很分明粗疏了,很不错,今天来下班吧😈。

总结

对于垃圾回收算法这一块,肯定要答到 GC Roots,以及各种垃圾回收算法,及他们的长处和毛病。

❤️/ 感激反对 /

以上便是本次分享的全部内容,心愿对你有所帮忙 ^_^

喜爱的话别忘了 分享、点赞、珍藏 三连哦~

欢送关注公众号 程序员巴士,来自字节、虾皮、招银的三端兄弟,分享编程教训、技术干货与职业规划,助你少走弯路进大厂。

正文完
 0