什么样的对象会被收集
- 可达性分析后,没有任何引用的对象(第一次标记)
- 该对象是否需要执行finalize()方法(第二次标记),不需要执行的对象直接判定死亡。
需要执行finalize()方法的对象放到F-Queue队列,等待虚拟机去执行。执行完成之后再进行可达性分析,没有任何引用的对象判定死亡。
其中finalize方法只会执行一次,下次如果再判定没有任何引用了,直接判定死亡。
Minor gc
步骤
1. 非GC时,新生代的分布是这样,eden区和s0区有object,s1区为空;
2. eden区满时,触发MinorGC,将eden区和s0区尚存活的object,复制到s1区,顺利完成后,s0区和s1区命名互换一下;
3. MinorGC 中存活的object如果超过tenuring threshold,会promote到老生代;
4. 每次MinorGC后,都会计算一个合理的tenuring threshold和各年代区的size,以及适时地调整size
Full gc
触发条件,归根到级还是old区放不下要进来的对象,才会出现full gc
(1)System.gc是建议jvm进行full GC(可以配置XX:+ DisableExplicitGC来禁止RMI调用System.gc)
(2)老年代空间不足(到了一定的年龄后,晋升到老年代,s区是正常的可以放得下)
(3)永久代(方法区)空间不足(PermGen space)
(4)CMS GC时出现promotion failed和concurrent mode failure
promotion failed是指s区放不下,old区也放不下
concurrent mode failure是指用户线程产生的浮动垃圾和晋升的对象在old区放不下
(5)统计到晋升的平均值大于老年代的剩余空间
(6)堆中分配很大的很大的对象(old连续的空间不足)
========================================
标记清除算法有个缺点就是垃圾收集后,内存是不连续的
CMS垃圾收集器采用的标记-清除算法,所以可以提供两个配置进行整理碎片。1.+UseCMSCompactAtFullCollection配置表示,full gc时开启内存碎片的合并整理,但是过程是无法是并发的。2.+CMSFullGCsBeforeCompaction配置表示,执行多少次不压缩的gc后,跟着来一次带压缩的(默认是0,表示每次进入full gc 时都进行碎片整理)