《新生代未指定分配》

1.问题背景

      接收到监控系统发出的提醒,提示线上环境一服务的老年代使用情况超过阈值,高达95%。这里针对问题的分析和处理,做一个简单的回顾和总结。

jdk环境:jdk8

2.排查过程

2.1处理过程

        (1)移除当前节点的流量,避免对线上的请求造成影响(线上环境中首先保证恢复集群可用,然后在定位问题)

        (2)生成当前机器的dump文件(jmap -dump:format=b,file=heapdump.hprof pid)

        (3)当前机器的gc日志文件

2.2推测原因

        (1)存在不可回收的大对象,导致老年代的内存空间被占用

        (2)新生代内存大小设置不合理,导致大部分对象直接存放老年代

2.3问题定位

当前jvm配置参数:

-Xms4G -Xmx4G -Xmn1G -Xss512K -XX:SurvivorRatio=8 -XX:+UseCMSCompactAtFullCollection -XX:MaxTenuringThreshold=10 -XX:CMSInitiatingOccupancyFraction=80 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/logs -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/logs/gc.txt

        2.3.1 分析dump文件

        使用idea分析当前的dump文件,发现当前系统中的对象没有过大文件,因为当前集群的主要职能就是接收消息,用来做任务的计算以及状态的更新,因此会产生大量的临时对象。

        2.3.2 分析gc日志

         查看最后一次gc日志,发现问题,from区和to区仅为1536K,与jvm配置的值存在很大的偏差。

按照配置文件计算from和to区的大小应该在100M左右,目前仅为1M左右。

(1)查看当前集群使用的垃圾回收器和内存配置

        发现集群使用的使用Parallel GC垃圾回收器,且Eden区的内存大小远超过配置的大小,怀疑Parallel GC垃圾回收器是否存在特殊的配置。最后定位到AdaptiveSizePolicy会根据每次gc动态的调整Eden、Survivor 区的大小;

参考文章:AdaptiveSizePolicy简介_useadaptivesizepolicy-CSDN博客

(2)查看当前集群是否开启AdaptiveSizePolicy

      发现集群中确实开启了AdaptiveSizePolicy的配置

(3)关闭AdaptiveSizePolicy配置

        Eden、Survivor 区的大小正常。问题解决  

3.结论

  • 应用使用 JDK 1.8,其默认回收器是 Parallel Scavenge,并且默认开启了 AdaptiveSizePolicy。
  • AdaptiveSizePolicy 动态调整 Eden、Survivor 区的大小,存在将 Survivor 区调小的可能。当 Survivor 区被调小后,部分 YGC 后存活的对象直接进入老年代。老年代占用量逐渐上升从而触发 FGC,导致较长时间的 STW。
  • 建议使用 CMS 垃圾回收器,默认关闭 AdaptiveSizePolicy。(-XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=80)
  • 建议在 JVM 参数中加上 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/logs -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/logs/gc.txt,让 GC log 更加详细,方便定位问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值