「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」。
垃圾回收算法
名词解释:
- 新生代垃圾回收Minor GC/Young GC
- 老年代垃圾回收Major GC/Old GC
- 全回收Full GC/回收整个堆和方法区
1.复制回收算法
将内存按照容量划分为大小相等的A、B两个区域,每次只是用一个区域。当A区域内存用完,将存活着的对象复制到B区域,然后清空A区,这样每次都是对半进行内存回收。
特点:
- 内存利用率只有50%
- 不存在内存碎片问题
- 复制对象时还需要修改对象的引用地址
目前
复制回收算法用于新生代,因为大部分对象的生命都很短暂,需要复制的对象并不是很多所以效率相对较高。
1.1JVM的Appel式回收
将堆内存的新生代划分为较大的Eden区和较小的两个一样大小的Survivor区(From、To),他们的比例在前文的图中已经说明是8:1:1,因为绝大部分的对象的生命很短暂,幸存区没必要设置太大。
2.标记-清除算法
此算法分为两个阶段:标记和清除
- 标记:根据
可达性分析算法扫描出可回收的对象,然后将对象进行回收标记。 - 清除:再次扫码被标记回收的对象进行垃圾回收。
特点:
- 因为需要扫描两遍,效率上略低
- 存在
内存碎片问题 - 适用于老年代
内存碎片
使用
标记-清除算法如上图所示,如果此时一个大对象(需要连续内存)需要分配,虽然堆内存总的空间是够用的,但是并没有连续的可用空间导致大对象放不下,提前造成GC。
3.标记-整理算法
此算法分为两步:标记和整理
- 标记:根据
可达性分析算法扫描出可回收的对象,然后将对象进行回收标记。 - 整理:将无用对象进行回收,将存活的对象往内存的一端移动,进行空间整理。
特点:
- 需要整理内存,效率略低
- 因为有整理,所以没有内存碎片问题
因为涉及到对象的移动,改变对象的引用地址,所以在整理的时候需要暂停用户线程,加重系统负担,目前此算法用户老年代的回收算法支持。