标记-清除算法(Mark and Sweep):
该算法分为两个阶段,
- 首先标记所有仍然在使用的对象;
- 然后清理所有未标记的对象。
缺点:
无法处理对象间的空洞,清理后出现内存碎片。
标记-压缩算法(Mark and Compact):
该算法是标记-清除算法的改进。
- 首先标记出存活的对象
- 然后将它们压缩到一端
- 清理掉所有未压缩的空间。
缺点:
该算法可以减少内存碎片的问题,但是效率相对较低,因为需要对存活的对象进行移动操作。
复制算法:
该算法将内存分为两块,每次只使用其中一块。
当这一块内存用尽后,将仍然存活的对象复制到另一块中。
缺点:
内存使用率不高,只有原来的一半,复制算法的效率会相对较低。
分代算法:
根据对象存活周期的不同将内存划分为几块,每块采用不同回收算法。
- JAVA分新生代和老年代:
- 新生代采用复制算法;
- 老年代采用标记压缩算法。
新生代里有 3 个分区 | 内存占比 | |
---|---|---|
Eden | 未进过GC的对象 | 8 |
From Survivor | 经过GC的对象,复制算法使用区域 | 1 |
To Survivor | 经过GC的对象,复制算法使用区域 | 1 |
1、新生代
垃圾回收: Minor GC ([ˈmaɪnər])
Young 新生代 第一次Minor GC, 存活对象移动, 年龄+1 Minor GC, 存活对象移动, 年龄+1 Minor GC, 存活对象移动, 年龄+1 年龄==15 或者达到年龄阈值, 存活对象移动到老年代 大数组直接进老年代
或者 对象大小大于PretenureSizeThreshold To Survivor From Survivor Eden Old 老年代
参数配置 | |
---|---|
-Xms | 表示初始化堆内存 |
-Xmx | 表示最大堆内存 |
-Xmn | 表示新生代的内存 |
-XX:SurvivorRatio | 8表示新生代的Eden占8/10,S1和S2各占1/10. |
-XX:MaxTenuringThreshold | 新生代-复制清除算法 年龄阈值设置( 默认15) |
-XX:PretenureSizeThreshold | 新生代- 大对象阈值设置( 默认0 ),对象大于阈值直接进老年代 |
2 、老年代
垃圾回收: MajorGC ( [ˈmeɪdʒər])
主要存放应用程序中生命周期长的内存对象。
MajorGC采用标记压缩算法:
- 首先扫描一次所有老年代,标记出存活的对象,MajorGC的耗时比较长,因为要扫描再回收。
- 然后回收没有标记的对象。
- 存活的对象被移动到连续的内存区域中。
- 当老年代也满了装不下的时候,抛出OOM (Out of Memory)异常。
触发时机:
老年代的对象比较稳定,所以MajorGC不会频繁执行。
- 新生代的对象进入老年代,导致空间不够用时触发。
- 无法找到足够大的连续空间 分配给 新创建的大对象时触发。