今天一个同学问我:"我排查问题时总是遇到,jmap -heap或-histo 不能用,是不是我们机器配置有啥问题哇? " 分享下这个case的解决过程。
登上同学说的那台不能用的机器,执行jstack,报错:
“get_thread_regs failed for a lwp”
这个问题以前碰到过,但忘了当时是什么原因了,执行其他的jmap -histo什么也卡着不动。
既然jstack没法弄,就pstack看看进程到底什么状况吧,于是pstack [pid]看,发现有一个线程的堆栈信息有点奇怪:
#0 0x00000038e720cd91 in sem_wait ()
对系统函数不太懂,但总觉得sem_wait这个有点奇怪,于是Google之,基本明白了这个是由于进程在等信号,这个时候通常会block住其他所有的线程,于是立刻ps看了下进程的状态,果然进程的状态变成了T,那上面碰到的所有现象都很容易解释了,于是执行:kill -CONT [pid],一切恢复正常。
继续查为什么进程状态会变成T,问问题的同学告诉了下我他在机器上执行过的一些命令,我看到其中一个很熟悉的命令:jmap -heap,看过我之前文章的同学估计会记得我很早以前分享过,在用cms gc的情况下,执行jmap -heap有些时候会导致进程变T,因此强烈建议别执行这个命令,如果想获取内存目前每个区域的使用状况,可通过jstat -gc或jstat -gccapacity来拿到。
到此为止,问题终于搞定,以后碰到jstack/jmap等不能用的时候,可以先看看进程的状态,因此还是那句话,执行任何一句命令都要清楚它带来的影响。
手头还有另外一个case,折腾了一个多星期了还是没太有头绪,case的现象是ygc越来越慢,但可以肯定不是由于cms gc碎片问题造成的,感兴趣的同学可以拿这个case去玩玩,如果能告诉我原因就更好了,:),执行下面的代码,启动参数可以为
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xms512m -Xmx512m -Xmn100m -XX:+UseConcMarkSweepGC;
import com.thoughtworks.xstream.XStream;
public class XStreamTest {
public static void main(String[] args) throws Exception {
while(true){
XStream xs = new XStream();
xs.toString();
xs = null;
}
}
}
应该就可以看到ygc的速度从10+ms一直增长到100+ms之类的...
案例分析: