又一个陷入困局的case,求助

最近排查case实在是非常的不顺,又碰到了一起至今为止还无解的case,分享并顺带求助下。

这个case的现象是应用负载很低,但执行jstack或jmap都提示需要加-F来强制执行,碰到这样的现象,自己常用的一招就是先gcore pid生成下core dump,然后再用jstack/jmap去拿,jstack从core dump里提取java stack信息的时候报错了,于是只好jmap去提取内存dump信息,这个成功了,放到内部的web版的mat上一看,内存使用很正常,线程也挺正常的。

于是用pstack去看那个java的进程到底在做什么,诡异的是看到的是这个java进程正在执行cms gc,执行到MarkSweep::follow_stack这一步,一直不动,这太奇怪了,这个时候刚好应用这边的人告诉我一个信息是,卡住之前gc log里显示一直在做cms gc。

到这个阶段为止,这个现象仍然是非常的奇怪,第一次碰到一个应用一直做cms gc然后到卡死的状况,百思不得其解,在一通瞎折腾后,突然看到这个进程的状态与众不同的处于T状态,T状态表明进程处于STOPPED或TRACED状态,那就可以解释为什么会卡住了,猜想应该没人做TRACE,于是就执行了下kill -18 pid,进程恢复了,gc log里开始继续输出信息,一直在做full gc,后来查明进程进入T状态的原因是之前执行jmap后异常退出,导致进程变成T状态了,但为什么会变成这个细节目前还没去查,如果有人知道也欢迎反馈。

到这步,理论上问题就好查了,进入了典型的OOM排查模式,悲催的是dump内存,还是失败,gcore再jmap,分析后显示只占了几十M的内存,这还是不对,只好再次尝试执行jmap –dump,在dump了两次后终于成功了,拿着这个dump文件开始分析。

dominator tree显示内存主要是被三个线程占用,每个线程里占用最多的都是com.sun.tools.javac.util.ListBuffer,三个线程都是在执行com.sun.tools.javac.Main.compile中产生出来的,而且都是在compile同一个java代码。

对这块的机制不太熟,猜想莫非是多个线程compile同一段代码会出现并发问题,导致死循环了,于是自己在本机模拟写了一个多线程compile同一个java代码的测试,没碰到问题,在生产环境里也用真实环境去测试了下,也没重现。

这个case到目前仍然是这个状况,完全不明白为什么compile产生出了一个暴大的ListBuffer,不知道有没有看官们碰到过类似问题呢,求建议或帮助。

—————————–
这个case爆出后,前两天还出现了一个同学在线上执行jmap -heap,然后导致进程进入T状态,这个有可能是两个原因,一是在用cms gc的情况下,有些时候jmap -heap的输出会一直循环,然后就卡住了,另一种就是执行的时候异常退出了,所以我以前给的建议一直是不要在生产环境执行jmap -heap,jstat完全可以满足需求,而且更安全。

—————————–
上篇文章中提及到一个tomcat支持长连接的问题,里面有说到很难找到文章清晰的讲解tomcat的三种connector(apr、nio、bio)模式的工作原理,同事@宏江 同学写了一篇很不错的文章,让自己受益匪浅,推荐给大家看看,感兴趣的可以点击阅读原文

=============================
欢迎关注微信公众号:hellojavacases

关于此微信号:
分享Java问题排查的Case、Java业界的动态和新技术、Java的一些小知识点Test,以及和大家一起讨论一些Java问题或场景,这里只有Java细节的分享,没有大道理、大架构和大框架。

公众号上发布的消息都存放在http://hellojava.info上。

发表评论

电子邮件地址不会被公开。 必填项已用*标注


*