Java堆内存富余却疯狂FullGc问题排查

 刚上线了一个新的应用集群,第二天和第三天收到了应用FullGc超过阈值的报警短信。但是观察报警Java实例的jvm监控,堆内存仅仅用了1G多一点,还富余近700M。很困惑,剩余这么多内存没被使用,那么说明老年代内存是充足的才对啊!

    同事提醒我是不是申请了什么大对象,诚然,老年代只会有两种类型的对象,1,多次Minor Gc中存活的小对象,2,大对象,即超过了PretenureSizeThreshold这个阀值直接分配到老年代的对象。一般疯狂Full Gc的原因就是程序申请大对象导致的。这回还是跟大对象有关吗?

    针对报警的实例进程执行jstat -gcutil 命令,拿到了这个java进程的内存个个代的使用百分比。

    发现P的使用率是98%,P,即 Permanent Generation,永久代。也就是说永久代的使用率已经超过了98%。于是问题明了了。FullGc,大家很容易想到的是Old Generation内存爆了导致的!但是这不是唯一的条件,永久代内存回收也是归FullGc管的!于是强烈建议我们的监控界面添加永久代的监控。永久代能回收什么呢?一,废弃的字符串常量,二,不再被引用的class对象。

    再针对这个实例执行  jstat -gccapacity pid 命令,发现这个实例的永久代仅仅给了82M。82M意味着什么,永久代的默认堆内存大小。

    果断添加JVM的永久代参数,-XX:PermSize=512M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/im.**.com/ 。顺便加上堆内存OOM的自动dump参数。


jstat工具类:

http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值