一次应用OOM排查

一次应用OOM排查

前段时间系统经常出现OOM,每次出现之后系统会出现各种问题,临时解决方案只能是重启,然后等找到问题后再发布解决。

 

线上问题日志如下:

1 Exception in thread "msgWorkTP-811568603-1-thread-6" java.lang.OutOfMemoryError: Java heap space
2  
3 Exception in thread "schedulerFactory_QuartzSchedulerThread" java.lang.OutOfMemoryError: Java heap space
4  
5 Exception in thread "server-timer" java.lang.OutOfMemoryError: Java heap space
6  
7 Exception in thread "Tracer-AsyncAppender-Thread-CommonAppender" java.lang.OutOfMemoryError: Java heap space


线上遇到OOM需要做两件事情第一个是dump内存,第二个是看下GC日志。 1:dump内存 使用jmap命令dump内存,需要注意的是,在linux JDK1.6某个版本里使用jmap可能会让系统挂掉,可以通过-d64来解决。

1 jmap -J-d64 -dump:format=b,file=dump.bin PID

一般dump下来的内存有几个G,而我这次在线上dump下来只有200M,说明jmap有问题,这个时候可以用gcore 把整个内存dump出来,然后再使用jmap把core dump转换成heap dump。命令如下:

1 $ jmap  -permstat  /opt/taobao/java/bin/java core.17024

因为我们没有线上权限,又担心dump的时候系统容易挂掉,所以我们在JVM里加了个参数,在OOM的时候自动dump内存,

1 -XX:+HeapDumpOnOutOfMemeryError

2:查看gc日志

如果没有任何JVM参数设置,gc日志默认打印在stdout.log文件里,里面可能会打其他的日志,而且GC日志也不会输出时间,所以在JVM启动参数里最好加以下命令,规范下GC日志输出到/home/admin/logs/gc.log,并且打印GC时间。

1 -XX:HeapDumpPath=/home/admin/logs -Xloggc:/home/admin/logs/gc.log  -XX:+PrintGCDetails -XX:+PrintGCDateStamps

在查看GC日志里发现concurrent mode failure问题,日志如下:

(concurrent mode failure): 1146697K->1146697K(1146880K), 1.0353630 secs] 1773385K->1697954K(1773568K),

这个问题是因为CMS(Concurrent Mark-Sweep)垃圾回收器在做fullgc,还没到达回收的阶段,但是年轻代又有新对象晋升到年老代,而年老代又没有足够空间了,只能全停机,进行fullgc。但是从日志上看没有释放多少空间,要么是堆不够大,要么是泄露,先调大堆,如果是泄露,还是会重现,如果不是泄露,就稳定了。于是我们进行了JVM参数调整,系统有8G内存,我们把JVM堆内存升到3.8G,修改参数XX:CMSInitiatingOccupancyFraction=60,让年老代在达到60%的时候进行CMS回收,这样在进行回收时候年老贷至少还有3800*0.4=1520m空间,就算把整个年轻代塞进去也没有问题。

1 -server -Xms3800m -Xmx3800m -Xmn1500m -Xss256k -XX:PermSize=340m -XX:MaxPermSize=340m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=60 -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicitGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/logs -Xloggc:/home/admin/logs/gc.log -Dcom.sun.management.jmxremote.port=9981 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dfile.encoding=UTF-8

参数调整后,过了几天还是出现OOM,可以断定是内存溢出导致的,通过自动dump下来的内存文件很快发现有一个对象占用内存非常大,解决后系统恢复正常。

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 一次应用OOM排查


0

方 腾飞

花名清英,并发网(ifeve.com)创始人,畅销书《Java并发编程的艺术》作者,蚂蚁金服技术专家。目前工作于支付宝微贷事业部,关注互联网金融,并发编程和敏捷实践。
Favorite添加本文到我的收藏
  • Trackback 关闭
  • 评论 (5)
    • lytofb
    • 2016/04/07 3:45下午

    思路很好,学习了

  1. 那个“占用内存非常大”的对象是由于内存泄漏导致占用的空间持续增长么?

    • miaomiaoweiwei
    • 2016/04/20 12:07下午

    -XX:+HeapDumpOnOutOfMemoryError 这个参数memery字母写错了,memory应该是。

您必须  登陆 后才能发表评论

return top

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值