简介
说明
本文介绍Java的垃圾回收,包括:Young GC的触发时机,Full GC的触发时机,System.gc()作用。
Young GC(Minor GC)
什么时候会触发Minor GC?
- 大多数情况下,对象在年轻代中的Eden区进行分配,若Eden区没有足够空间,就会触发YGC(Minor GC)。
Full GC(Major GC)
简介
FGC处理的区域包括年轻代和老年代。
什么时候会触发Full GC?
- 老年代的内存使用率达到了一定阈值(默认是92% 通过-XX:MaxTenuringThreshoId设置)
- 情景1:Survivor区进行了15次清理后还没清理的对象,则放到老年代。
- 次数这个阈值是可以设置的:-XX:MaxTenuringThreshold(默认是15)
- 情景2:Minor GC时的检查
- 执行Minor GC时,JVM会先检查Survivor空间是否够用
- 如果够用则直接进行Minor GC
- 如果不够用,则检查老年代最大连续可用空间是否大于新生代的总和或者历次晋升到老年代的对象的平均大小
- 如果大于,则直接执行Minor GC(这个时候执行是没有风险的)。
- 如果小于,则直接执行Full GC
- JDK7及之后,空间分配担保参数:-XX:HandlePromotionFailure就失效了,无需考虑这个。
- 情景3:使用了大对象
- 大对象会直接进入老年代。比如:一次加载过多数据到内存(比如SQL查询未分页),导致大对象进入老年代。
- 相关参数:-XX:PretenureSizeThreshold。若对象大小大于此值,就会绕过新生代, 直接在老年代中分配。
- Metaspace(元空间)扩容到了-XX:MetaspaceSize 参数的指定值。(元空间在空间不足时会进行扩容)
- 程序执行了System.gc()
- 只是建议JVM执行FGC,并不一定会执行
- jmap 加了:live参数
- 例如:
- jmap -histo:live <pid>;
- jmap -dump:live,format=b,file=heap.bin <pid>
- 其他
- 上一次GC之后Heap的各域分配策略动态变化
- RMI等的定时触发
- YGC时的悲观策略