高频面试题-你知道垃圾回收机制涉及哪些算法吗?


theme: smartblue

这是我参与更文挑战的第13天,活动详情查看: 更文挑战

说到垃圾回收,首先就要先要了解垃圾回收机制涉及到的算法。

如果不了解JVM可以先去看看这几篇文章。

高频面试题-请聊一下JVM的内存结构!

高频面试题-请聊一下JVM中堆和栈的区别!

面试官问到这个问题,是为了要考察一下你对垃圾回收是否是一知半解,又或者是充大尾巴狼,毕竟这种情况太多了。

所以,我们要想征服面试官,要想从事更高的职位,拿更高的薪水,就要对知识理解透彻。

垃圾回收机制中涉及到的算法有标记清除算法、复制算法、标记整理算法、分代收集算法等。

接下来进行一一的解释。

标记清除算法

从字面意思上来看,就能看出这个算法有着两个操作,一个是标记,另一个是清除,先进行标记,再进行清除。

为了进行垃圾回收,我们首先要知道哪些是可以被回收的,所以‘标记’应运而生。

标记:通过根节点(GC Roots),把所有从GC Roots开始的对象进行标记,而后未被标记的对象就会被视为已经无用,也就是可以回收的对象。

清除:清除掉所有未被标记的对象。

适用场景

适用于对象存活率高的场景。

缺陷

会产生大量的内存碎片,每次清除原有对象的同时,就会把原有对象占用的内存空间给腾出来。

仅仅只是将空间腾出来的话,就可能会导致内存的不连续,从而产生大量的内存碎片。

当程序中有一个较大的对象想要放入内存时,需要占用一大段连续内存,这时候的内存中因为都是碎片,没有连续的内存,就会导致程序再去调用算法进行垃圾回收。

复制算法

该算法依然会去标记目前存活的对象,但与标记清除算法不同。

在标记之后,复制算法会将目前存活的对象复制+移动到另一块内存中,然后将原来的内存块全部清除掉。

这里的复制+移动,是要将原内存块中的对象顺序排列成连续性的,以留存出更大具有连续性的内存。

所以我们可以得出一个结论,就是复制算法必须要有两块内存才可以实施。

适用场景

适用于对象存活率低的场景,只有存活率够低,复制的时候所消耗的性能则会越低。

缺陷

缺点就是必须要有两块内存,这样就会导致本来可以任其获取的内存目前缩水了一半,这也是复制算法不能全部应用在虚拟机内存的原因。

移动的时候也会消耗一定的性能。

因为是复制+移动,所以不会留下内存碎片。

标记整理算法

标记整理算法,当然是先标记,再整理了。

该算法继续沿用了标记功能,在标记之后,先将存活对象都全部移动到内存的一端,然后根据最后一个存活对象的位置,将在其之后的所有空间清理掉。

适用场景

中规中矩,均可。

缺陷

并没有非常明显的缺点,主要还是因为解决碎片化和内存消耗过大的问题衍生出来的。

相对于标记清除算法,该算法不会产生大量碎片,是标记清除算法的改良版。

相对于复制算法,该算法不会无端占用过多的内存。

分代收集算法

该算法是目前Java虚拟机中使用的算法,主要是将前面几种算法归结在一起,然后在特定的情况下使用特定的算法。

具体如下:

还记得老年代占了多大的内存空间吗?

老年代中的对象存活率高,大对象也居多,内存占用打,又加上程序在运行时可能会存在大对象,所以这里不能产生过多的内存碎片,这些问题说明了不能使用标记清除算法和复制算法;so 老年代的垃圾回收要使用标记整理算法。

还记得新生代里面有哪些内存块吗?

分别是Eden、To Survivor、From Survivor三个内存空间,这里的两个Survivor区就是为了复制算法准备的。

加上新生代中存放的对象一般存活率很低,所以复制算法再合适不过了。

垃圾回收机制涉及的算法我们这就说完了,希望大家可以找到满意的工作,加油!

你可能感兴趣的:(算法,java,jvm,面试,oom)