大厂面试选拔最后的拉分题:垃圾回收算法

​ 秋招落入尾声,春招正在向广大校招程序猿们招手,对很多准备跳槽的在职人员来说,金三银四也是快到了,是时候补一下垃圾回收算法了。垃圾回收算法几乎是大厂筛人的利器,稍微有点答不好就直接给pass了,所以基本功很重要,洪爵本期带领大家一起学习面试最常问到的:标记-清除算法标记-复制算法标记-整理算法

标记-清除算法

​ 标记清除算法作为最早出现的垃圾回收算法之一,许多后续出现的GC算法都会和它做比较。标记清除顾名思义,先标记清除。首先给所有需要回收的对象打上标记,第二步回收所有打上标记的对象;或者反过来,标记所有存活的对象,第二步回收全部没有打上标记的对象。

​ 不知道大家有没有思考过,为什么不能边标记边删除呢?第一个是说功能的解耦开来,需要给对象打上标记的可能不仅仅只有标记-清除场景,需要把每个动作区分开来,标记是标记,回收是回收。但这并不是最主要的原因,了解过的同学或许知道,标记一个对象是否存活使用的是可达性分析算法,而可达性分析是需要STW(STOP THE WORLD)的,为了尽可能减少STW的时间,动作解耦开来是很有必要的。关于如何标记对象是否存活,洪爵会单独开一期讲解,这里不多赘述。

大厂面试选拔最后的拉分题:垃圾回收算法_第1张图片

​ 标记清除算法清理前和清理后如上图所示,从中我们能发现很多问题。第一个最显而易见的是内存碎片化问题,清除之后,内存会出现大量不连续的情况,假设后续需要分配大小为5个空间的对象,无法找到连续的内存块为其初始化,但内存中未使用的空间远远不止5个大小,导致不得不触发另一次GC动作;第二个问题是有关于执行效率,对象越多标记和清除的时间就越久GC效率降低

标记-复制算法

​ 为了解决标记-清除算法带来的大量对象需要回收导致执行效率低下的问题,标记-复制算法被提了出来。它将可用内存空间分为两个大小相等的块,假设为A和B。每次只使用其中一块内存,假设为A区,当A区的内存使用完了,就将还存活着的对象移到另一个半区B,然后把A区清空,留待B区使用完移到A区。但如果内存中大多数都是存活的对象,那么使用标记复制算法的效率会非常的低,因为会产生很多内存复制的开销;但如果是相反的情况,大多数对象都需要被回收,那么需要复制到另一个半区的效率就会提高,并且每次只需要对半区进行清理,也不会有内存碎片化的问题。只需要移动堆顶指针按顺序进行分配就可以了,当然了它的缺点也是非常的明显,可用的内存减少到了原来的一半
大厂面试选拔最后的拉分题:垃圾回收算法_第2张图片

​ 据统计,新生代中98%对象都会在第一轮GC中被回收,所以标记-复制算法的思想在很多虚拟机中都用来回收新生代,比如说HotSpot虚拟机中的Serial、ParNew等新生代的收集器就是用到了类似的策略,将新生代分为两个部分,一个是Eden区,两个Survivor区,这个洪爵后续章节会开展说明,这里只做一个简单的了解。

标记-整理算法

​ 当标记-复制算法面对的是老年代的对象(即一直存活的对象),效率大大降低,过多无用的复制 + 浪费 50% 的内存空间。针对这种老年代对象,标记-整理算法被设计出来,首先还是标记的过程,这个过程和标记-清除算法、标记-复制算法一样,标记存活的对象,第二步则和其他两个算法都不相同,标记-整理算法的第二步是将还存活的对象移到内存空间的一端,然后清空掉边界外的内存,而对对象移动的操作必须全程暂停Java进程的其他作业,有个很形象的说法叫做STW,即STOP THE WORLD。

大厂面试选拔最后的拉分题:垃圾回收算法_第3张图片

​ 以上三个垃圾回收算法算是比较基础的,面试中一定不能马虎,让面试官充分看到你的基本功是否扎实,如果你连基本的GC算法都讲的不明不白,后面你答出来各种吊炸天收集器,以及怎么吊炸天都没用。

​ 加油,打工人!

大厂面试选拔最后的拉分题:垃圾回收算法_第4张图片
愿每个人都能带着怀疑的态度去阅读文章并探究其中原理。

道阻且长,往事作序,来日为章。

期待我们下一次相遇!

你可能感兴趣的:(java,程序人生,寻找offer)