JVM有四种垃圾回收算法:
- 标记清除算法(Mark-Sweep)
- 复制算法(copying)
- 标记整理算法(Mark-Compact)
- 分代收集算法(Generational)
标记清除算法(Mark-Sweep):
标记清除算法分为两个阶段:
1、通过可达性分析,标记出所有需要回收的对象。
2、回收被标记的对象所占用的空间。
优点:实现简单、不需要对象进行移动。
缺点:标记、清除过程效率低,产生大量不连续的内存碎片,提高了垃圾回收的频率。
![](http://justzqq.com/wp-content/uploads/2023/03/image-1.png)
复制算法(copying):
为了解决清除算法效率不高的问题,产生了复制算法。
把内存空间划分为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用的区域,把存活对象复制到另一个区域中,最后将当前使用的区域的可回收的对象进行回收。
优点:按顺序分配内存即可,实现简单、运行高效、不用考虑内存碎片。
缺点:可用的内存大小缩为原来的一半,对象存活率高时会频繁进行复制。
![](http://justzqq.com/wp-content/uploads/2023/03/image-2.png)
标记整理算法(Mark-Compact):
标记整理算法,与标记清除算法不同的是,在标记可回收的对象后将所有存活的对象压缩到内存的一端,使用它们紧凑的排列在一起,然后对端边界以外的内存进行回收。回收后,已用和未用的内存都各自一边。
优点:解决了标记清理算法存在的内存碎片问题。
缺点:仍需要进行局部对象移动,一定程度上降低了效率。
![](http://justzqq.com/wp-content/uploads/2023/03/image-4.png)
分代收集算法(Generational):
当前商业虚拟机都采用分代收集的垃圾收集算法。分代收集算法是根据对象的存活周期将内存划分为几块。一般包括新生代(年轻代)、老年代和永久代。新生代基本采用复制算法,老年代和永久代采用标记整理算法。
在新生代中使用复制算法,但是在老年代就不能选择复制算法了,因为老年代的对象存活率会较高,这样会有较多的复制操作,导致效率变低。而标记清除算法在老年代中的效率不高,在内存回收后容易产生大量内存碎片。因此老年代使用标记整理算法。
![](http://justzqq.com/wp-content/uploads/2023/03/image-3.png)