JVM核心原理和性能优化总结

对象什么时候进入老年代?

  • 一个对象在年轻代里躲过15次垃圾回收,年龄太大了,进入老年代
  • 对象太大了,超过了一定的阈值,直接进入老年代,不走年轻代
  • 一次Young GC过后存活对象太多了,导致Survivor区域放不下了,这批对象会进入老年代
  • 可能几次Young GC过后,Surviovr区域中的对象占用了超过50%的内存,此时会判断如果年龄1+年龄2+年龄N的对象总和超过了Survivor区域的50%,此时年龄N以及之上的对象都进入老年代,这是动态年龄判定规则

老年代的GC是如何触发的?

一旦老年代对象过多,就可能会触发Full GC,Full GC必然会带着Old GC,也就是针对老年代的GC,而且一般会跟着一次Young GC,也会触发永久代的GC。

  • 老年代自身可以设置一个阈值,有一个JVM参数可以控制,一旦老年代内存使用达到这个阈值,就会触发Full GC,一般建议调节大一些,比如92%;
  • 在执行Young GC之前,如果判断发现老年代可用空间小于了历次Young GC后升入老年代的平均对象大小的话,那么就会在Young GC之前触发Full GC,先回收掉老年代一批对象,然后再执行Young GC;
  • 如果Young GC过后的存活对象太多,Survivor区域放不下,就要放入老年代,要是此时老年代也放不下,就会触发Full GC,回收老年代一批对象,再把这些年轻代的存活对象放入老年代中。

触发Full GC几个比较核心的条件就是这几个,总结起来,其实就是老年代一旦快要搞满了,空间不够了,必然要垃圾回收一次。

正常情况下GC频率

正常情况下的系统,会有一定频率的Young GC,一般在几分钟一次Young GC,或者几十分钟一次Young GC,一次耗时在几毫秒到几十毫秒的样子,都是正常的。
正常的Full GC频率在几十分钟一次,或者几个小时一次,一天一次,几天一次,这个范围内都是正常的,一次耗时应该在几百毫秒的样子。

用jstat等工具去观察JVM的运行内存模型:
Eden区的对象增长速率多块?
Young GC频率多高?
一次Young GC多长耗时?
Young GC过后多少对象存活?
老年代的对象增长速率多高?
Full GC频率多高?
一次Full GC耗时?

频繁Full GC的几种常见原因
系统承载高并发请求,或者处理数据量过大,导致Young GC很频繁,而且每次Young GC过后存活对象太多,内存分配不合理,Survivor区域过小,导致对象频繁进入老年代,频繁触发Full GC。
系统一次性加载过多数据进内存,搞出来很多大对象,导致频繁有大对象进入老年代,必然频繁触发Full GC
系统发生了内存泄漏,莫名其妙创建大量的对象,始终无法回收,一直占用在老年代里,必然频繁触发Full GC
Metaspace(永久代)因为加载类过多触发Full GC
误调用System.gc()触发Full GC

如果jstat分析发现Full GC原因是第一种,那么就合理分配内存,调大Survivor区域即可。
如果jstat分析发现是第二种或第三种原因,也就是老年代一直有大量对象无法回收掉,年轻代升入老年代的对象并不多,那么就dump出来内存快照,然后用MAT工具进行分析即可

如果jstat分析发现内存使用不多,还频繁触发Full GC,必然是第四种和第五种,此时对应的进行优化即可。
 

JVM参数模板
-Xms4096M -Xmx4096M -Xmn3072M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFaction=92 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSParallelInitialMarkEnabled -
XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -XX:+PrintGCDetails -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/app/oom

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值