标记 - 清除算法(Mack and Sweep)
标记:从根集合进行扫描,对存活的对象进行标记
清除:对堆内存从头到尾进行线性遍历,回收不可达对象内存
-
缺点:
- 会导致内存碎片化
如图:如果新元素需要三个连续的内存空间,没有则会一直触发GC,直到
复制算法(Copying)
1)分为对象面和空闲面
2)对像在对象上创建
3)存活的对象被从对象面复制到空闲面
4)将对象面所有对象内存清楚
商用的虚拟机基本用这个算法回收粘性带
不用考虑随眠期概况,只需要移动堆顶指针按顺序分配,需要是一次性清除。
-
优点
- 解决碎片化问题
顺序分配内存简单高效
适用于存活率高的对象
缺点
- 无法应对对象存活率高的时候,要进行较多的复制操作
会浪费50%的空间,或要有额外的空间担保
要应对100%的情况
标记 - 整理算法(compacting)
标记:从根集合进行扫描,对存活的对象进行标记。
清除:移动所有存活的对象,且按照内存地址一次排列,然后将末端内存地址以后的内存全部回收。
-
特点
- 避免了内存的不连续性
不用设置两块内存互换
适用于存活率高的场景
分带收集算法
垃圾回收的组合拳
按照生命周期的不同划分区域采用不同的垃圾回收算法
目的:提高JVM的回收效率
GC的分类
Minor GC:发生在年轻代中的垃圾收集工作,采用复制算法
Full GC:与老年代相关,老年代的回收一般会伴随年轻代的收集。
年轻代
Eden区:对象被创建内存首选分配在Eden区
两个Survivor区:分为 rom区 和 to区,不是固定的,会伴随着垃圾回收的进行转换。
回收过程
如何晋升到老年代
经历一定的Minor次数依然存活的对象(默认15岁,
-XX:MaxTenuringThreshold,制定)
Survivor区存不下的对象
新生成的大对象(-XX:+PretenuerSizeThreshold)
常用的调优参数
-XX:SurvivorRatio:Eden和Survivor的比值,默认8:1
-XX:NewRatio:老年代和年轻代内存大小的比例
-XX:MaxTenuringThreshold:对象从年轻代晋级到老年代GC次数的最大阈值
老年代(存放生命周期较长的对象)
标记 - 整理算法
标记 - 清除算法
Full GC 和 Major GC
Full GC 比 Minor GC慢,但执行频率低
触发Full GC但条件
老年代空间不足
永久代空间不足
CMS GC时出现promotion Failed,concurrent mode failure
Minor GC晋升到老年代的平均大小大于老年代的剩余空间
调用System.gc()
使用RMI来进行RPC或管理的JDK应用,每小时执行1次 Full GC