垃圾收集算法

2021-06-25  本文已影响0人  云芈山人

垃圾收集算法涉及大量的程序细节,各平台的虚拟机操作内存的方法又各不相同,故而本篇只介绍几种算法的思想及其发展过程。

一、标记-清除算法(Mark-Sweep)

最基础的收集算法(后续算法都是以它的不足而改进得到,所以称最基础),分为”标记“和”清除“两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

二、复制算法(Copying)

为解决效率问题,复制(Copying)收集算法出现:它将内存按容量划分为大小相同的两块,每次只使用其中的一块。当一块内存用完了,就将还存活的对象复制到另外一块上面,然后再把以使用过的内存空间一次性清理掉。

这样使得每次都是对整个半区进行内存回收,内存分配时也不用考虑内存碎片化等复杂情况,只要移动堆顶指针,将顺序分配内存即可,实现简单,运行高效。

三、标记-整理算法(Mark-Compact)

根据老年代的特点,“标记-整理”(Mark-Compact)算法适时出现,标记过程仍然和"标记-清除"算法中一致,但是后续过程是让所有存活对象移至一端,然后直接清理掉端边界外的内存。

四、分代收集算法(Generational Collection)

目前大部分虚拟机都采用“分代收集”(Generational Collection)算法,他根据对象存活周期的不同,将内存划分为新生代和老年代,并采取不同的收集算法回收对象。

第一步:把 Eden 和From Survivor区域中存活的对象复制到 To Survivor 区域(如果有对象的年龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果 To Survivor 不够位置了,就通过分配担保机制提前转移到老年区);
第二步:清空Eden、From Survivor中的对象;
第三步:From Survivor与To Survivor位置互换,原先的To Survivor成为下一次GC的From Survivor区域(From Survivor作为)。


堆内存.png

分区收集算法

分区收集算法则将整个堆空间划分为连续的不同小区间,每个小区间独立使用,独立回收。这样做可以控制一次回收多少个小区间,根据目标提顿时间,每次合理地回收若干个小区间(而不是整个堆),从而减少一次GC所产生的停顿。

上一篇 下一篇

猜你喜欢

热点阅读