一、对象进入老年代的时机
1、youngGC15次还存活
2、存活对象同一批相同年龄的对象大于S区 50%,大于这批年龄的对象进入 老年区
3、大对象,超过XX:PretenureSizeThreshold设置,直接进入老年区
4、youngGC后存活对象大于suvivor,整体到老年区
二、minorGC触发时机
Eden区满触发
三、触发Minor GC之前,发生了什么
判断新生代所有对象与老年代可用内存大小,由此引入空间担保规则
youngGC之前的老年代空间担保规则
1)老年代可用空间 > 新生代所有对象总和 可放心minorGC
2)老年代可用空间 < 新生代所有对象总和
(XX:HandlePromotionFailure是否设置)是否允许担保失败 一般情况开启,可减少fullGC次数
如果设置:老年代可用空间 < 新生代youngGC后进入老年代的平均大小 fullGC顺带youngGC
老年代可用空间 > 新生代youngGC后进入老年代的平均大小
冒风险去youngGC
1、存活对象小于suvivor,直接进suvivor
2、存活对象大于suvivor,小于老年代可用空间,直接进老年代
3、存活对象大于suvivor,大于老年代可用空间,fullGC顺带youngGC
未设置:fullGC顺带youngGC
四、什么情况下youngGc之前提前fullGC?
1、老年代可用空间 < 新生代所有对象总和,且未设置空间担保规则
2、老年代可用空间 < 新生代所有对象总和,且设置空间担保规则,但是老年代可用空间 < 新生代youngGC后进入老年代的平均大小
3、老年代可用空间 < 新生代所有对象总和,且设置空间担保规则,且老年代可用空间 > 新生代youngGC后进入老年代的平均大小,
但是youngGC后,存活对象大于suvivor,大于老年代可用
4、-XX:CMSInitiatingOccupancyFraction=80 老年代占用空间大于80%,触发cms GC
当该比例设置较小时,容易发生concurrent mode failure ,自动用“Serial old” 回收器替换cms,然后强行stop the world ,
进行长时间的GCRoots追踪,标记出来垃圾对象,然后回收
五、什么情况下直接minorGc
1、老年代可用空间 > 新生代所有对象总和
2、老年代可用空间 < 新生代所有对象总和,且设置空间担保规则,且老年代可用空间 > 新生代youngGC后进入老年代的平均大小
六、如何干掉fullGC?
根据线上系统运行情况
1、判断动态年龄对象需要多少岁才会被垃圾回收
2、相同年龄对象无论什么时候不能大于S区50%
3、每次youngGC后,平均存活对象小于老年代大小,小于S区
4、根据线上运行情况,大对象设置,避免大对象跑到老年代
JVM参数集锦
-Xms4096M -Xmx4096M -Xmn3072M -Xss1M
-XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFaction=92 老年代占用空间大于92%,触发cms GC
-XX:+UseCMSCompactAtFullCollection cms gc后,stop the world ,要进行碎片整理工作
-XX:CMSFullGCsBeforeCompaction=0 执行多少次fullGC之后再执行一次内存碎片整理工作 默认0
-XX:+CMSParallelInitialMarkEnabled 开启初始化标记并行
-XX:+CMSScavengeBeforeRemark 在重新标记之前,先执行一次ygc
-XX:+DisableExplicitGC 禁止代码中显示调用GC
-XX:+PrintGCDetails
-Xloggc:gc.log 指定GC log
-XX:+HeapDumpOnOutOfMemoryError oom时输出堆文件信息
-XX:HeapDumpPath=/usr/local/app/oom