1、标记清除算法(MarkSweep)
执行步骤:
- 标记:遍历整个内存区域,对需要回收的对象打上标记。
- 清除:再次遍历内存,对标记过的内存进行回收。
图解:
缺点:
- 效率问题:遍历了两次内存空间(第一次标记,第二次清除)。
- 空间问题:容易产生大量内存碎片,当再需要一块比较大的内存时,虽然总的可用内存是够的,但是由于太过分散,无法找到一块连续的且满足分配要求的,因而不得不再次触发一次GC。
2、复制算法(Copying)
将内存划分为等大的两块,每次只使用其中的一块。
当一块用完了,触发GC时,将该块中存活的对象复制到另一块区域,然后一次性清理掉这块没有用的内存。
下次触发GC时将那块中存活的的又复制到这块,然后抹掉那块,循环往复。
图解:
优点:
相对于标记–清理算法解决了内存的碎片化问题,这种算法没有内存碎片。
因为复制的时候,会把存活的对象,聚拢在一起。效率更高(清理内存时,记住首尾地址,一次性抹掉)。
缺点:
浪费内存,内存利用率不高,每次只能使用一半内存。8G的内存,只能使用4G,这个是无法接受的。
3、标记整理算法
当对象的存活率比较高时,或者对象比较大时,用前面的复制算法这样复制过来,复制过去,没啥意义,且浪费时间。
执行步骤:
标记:对需要回收的进行标记
整理:让存活的对象,向内存的一端移动,然后直接清理掉没有用的内存。
图解:
缺点:复杂度更高
3个算法各有利弊,各自有各自的适用场景
4、分代收集算法
⽼年代⼀般使⽤“标记-清除”、“标记-整理”算法,年轻代⼀般⽤复制算法