JAVA crash后的不完全排查手段

打印GC,内存溢出dump
-server -Xms512m -Xmx512m -XX:NewSize=107m -XX:MaxNewSize=107m -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps  -Xloggc
:/home/admin/gc.log -XX:+HeapDumpOnOutOfMemoryError


gc log能够看到JVM 3代内存的大小状况,但感觉不太详细,只能初步查看到应用挂的时候内存是否正常.

PS:如果启动参数没有加打印gc log的参数,并且应用也不好重启的情况下,也可以动态打开gc(还没有试过,有场景了试下)
jinfo -flag PrintGCDetails=true [pid]


下面这个命令是在应用快挂掉时,手动进行应用的Thread Dump,确定crash时各个线程在做什么事.也就是能够一定程度确定出事范围.但是这个命令在java 进程突然退出时根本来不及执行.如果应用以较慢速度往宕机的方向发展或者应用执行速度非常慢,可以试着使用这个命令看下当时的所有线程在做什么事情.
kill -3 xxx > xxx.log


在java程序突然crash的时候,HeapDump是非常好用的.一般在启动参数中加入如下选项即可.
HeapDump的文件需要专用工具来分析,比如MAT(http://www.eclipse.org/mat/),可以导入HeapDump文件进行分析.然后给出可能出现问题的对象.一般快速crash都是某种对象或者资源实例爆发性增长造成.所以使用MAT能够很快找到原因.
XX:+HeapDumpOnOutOfMemoryError


另外一种HeapDump是主动去dump,而不是等到应用挂掉的时候利用启动参数去做。也可以参考
http://download.oracle.com/javase/6/docs/technotes/tools/share/jmap.html
jmap -dump:[live,]format=b,file=xxx  <pid>


在kill -3 pid 有时候无法使用的时候,jdk bin目录下的jstack也能起到类似作用。应用卡住挂起的时候,搜下这个日志locked标记,看是否都在等待某一个锁,再看堆栈最上层日志后查源码。
ps -aux | grep "java"  //查找到线程的pid
../java/jstack pid > xxx.log


另外简单介绍下一个比较牛x的工具,可以在线查看运行时某一个类没方法的输入输出等各种运行时信息而不必通过打日志重新发布排除故障-BTrace,这个暂时还没有使用到,找个时间试下。可以参考 毕老大 的详细介绍,这里也tips下:
http://blog.bluedavy.com/?p=185

猜你喜欢

转载自bucketli.iteye.com/blog/1119494