随笔记录:JVM 垃圾回收顺序
- 大多数情况下,对象优先在新生代 Eden 区中分配。当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC。
- 大对象,即需要大量连续内存空间的 Java 对象,容易导致内存中有不少空间就提前触发垃圾收集,以获取足够的连续空间来安置它们。
(1、目前大部分的分代垃圾收集器在新生代都采用了标记复制算法,不会产生内存碎片。
2、CMS,也被称为并发低停顿收集器,这里的并发指的是垃圾收集器与用户线程都在运行,即用户线程未被冻结,是一款回收老年代的垃圾收集器,采用了标记-清除算法,目的就是为了达到名字中的并发低停顿。初始标记,即标记一下 GC Roots 能直接关联到的对象,这个过程必须要“Stop the World”,但是速度很快。CMS 老年代内存碎片空间无法容忍时不的不触发触发 Full GC 时,开启内存碎片的合并整理。CMS 并发收集失败时会采用后备预案,碎片空间整理合并就不清楚啦~大概率也是~)
当复制对象时,大对象就意味着高额的内存复制开销。-XX: PretenureSizeThreshold 参数,指定大于该值的对象直接在老年代分配。 - 长期存活的对象,即达到一定年龄阈值的对象(存活一次年龄+1)会被晋升到老年代。
- 新生代 Survivor 空间中相同年龄的所有对象大小的总和大于 Survivor 空间的一半时,年龄大于或等于该年龄的对象就可以直接进入老年代,无需等待年龄阈值。
- 在发生 Minor GC 之前,检查老年代最大可用连续时间是否大于新生代所有对象总和,if true,这 Minor GC 可用确保是安全的,if false,则先查看 -XX: HandlePromotionFailure 参数的设置值是否允许空间分配担保失败,if true,继续检查老年代最大可用连续空间是否大于历次晋升到老年代对象的平均大小,if ture,尝试进行 Minor GC,有风险,如果失败,会重新发起一次 Full GC(GC 时间更长了,但可用避免 Full GC 过于频繁),if false,改为进行一次 Full GC。
- JDK 6 Update 24 之后, -XX: HandlePromotionFailure 不会影响到空间分配担保策略,规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会 Minor GC,否则进行 Full GC。