JVM致命错误日志(hs_err_pid.log)分析
2015-09-02 13:06
344 查看
JVM致命错误日志(hs_err_pid.log)分析
发表于5天前(2015-08-28 17:10)当jvm出现致命错误时,会生成一个错误文件 hs_err_pid<pid>.log,其中包括了导致jvm crash的重要信息,可以通过分析该文件定位到导致crash的根源,从而改善以保证系统稳定。当出现crash时,该文件默认会生成到工作目录下,然而可以通过jvm参数指定生成路径(JDK6中引入):
?
日志头文件
导致crash的线程信息
所有线程信息
安全点和锁信息
堆信息
本地代码缓存
编译事件
gc相关记录
jvm内存映射
jvm启动参数
服务器信息
下面用一个crash demo文件逐步解读这些信息,以便大家以后碰到crash时方便分析。
日志头文件
日志头文件包含概要信息,简述了导致crash的原因。而导致crash的原因很多,常见的原因有jvm自身的bug,应用程序错误,jvm参数配置不当,服务器资源不足,jni调用错误等。现在参考下如下描述:
?
PS:除了“SIGSEGV(0xb)”以外,常见的描述还有“EXCEPTION_ACCESS_VIOLATION”,该描述表示jvm crash时正在执行jvm自身的代码,这往往是因为jvm的bug导致的crash;另一种常见的描述是“EXCEPTION_STACK_OVERFLOW”,该描述表示这是个栈溢出导致的错误,这往往是应用程序中存在深层递归导致的。
还有一个重要信息是:
# Problematic frame:
# J org.apache.http.impl.cookie.BestMatchSpec.formatCookies(Ljava/util/List;)Ljava/util/List;
这表示出现crash时jvm正在执行的代码,这里的“J”表示正在执行java代码,后面的表示执行的方法栈。除了“J”外,还有可能是“C”、“j”、“V”、“v”,它们分别表示:
C: Native C frame
j: Interpreted Java frame
V: VMframe
v: VMgenerated stub frame
J: Other frame types, including compiled Java frames
加上前面对SIGSEGV(0xb)”的分析,现在可以断定是JIT动态编译导致的该错误。
查阅资料发现:
此异常是由于jdk JIT compiler optimization 导致,bug id 8021898,官网描述如下:
?
到这里该问题已经分析出原因了,但是咱们可以再深入一步,分析下其它信息。
导致crash的线程信息
文件下面是导致crash的线程信息和该线程栈信息,描述信息如下:?
VMThread:jvm的内部线程
CompilerThread:用来调用JITing,实时编译装卸class 。 通常,jvm会启动多个线程来处理这部分工作,线程名称后面的数字也会累加,例如:CompilerThread1
GCTaskThread:执行gc的线程
WatcherThread:jvm周期性任务调度的线程,是一个单例对象。 该线程在JVM内使用得比较频繁,比如:定期的内存监控、JVM运行状况监控,还有我们经常需要去执行一些jstat 这类命令查看gc的情况
ConcurrentMarkSweepThread:jvm在进行CMS GC的时候,会创建一个该线程去进行GC,该线程被创建的同时会创建一个SurrogateLockerThread(简称SLT)线程并且启动它,SLT启动之后,处于等待阶段。CMST开始GC时,会发一个消息给SLT让它去获取Java层Reference对象的全局锁:Lock
后面的"catalina-exec-251"表示线程名,带有catalina前缀的线程一般是tomcat启动的线程,“daemon”表示该线程为守护线程,再后面的“[_thread_in_Java”表示线程正在执行解释或者编译后的Java代码,关于该描述其它类型还可能是:
_thread_in_native:线程当前状态
_thread_uninitialized:线程还没有创建,它只在内存原因崩溃的时候才出现
_thread_new:线程已经被创建,但是还没有启动
_thread_in_native:线程正在执行本地代码,一般这种情况很可能是本地代码有问题
_thread_in_vm:线程正在执行虚拟机代码
_thread_in_Java:线程正在执行解释或者编译后的Java代码
_thread_blocked:线程处于阻塞状态
…_trans:以_trans结尾,线程正处于要切换到其它状态的中间状态
最后的“id=205044”表示线程ID,stack(0x00007fb58f435000,0x00007fb58f536000)表示栈区间。
“siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000003f96dc9c6c”这部分是导致虚拟机终止的非预期的信号信息:其中si_errno和si_code是Linux下用来鉴别异常的,Windows下是一个ExceptionCode。
所有线程信息
再下面是线程信息:?
安全点和锁信息
再下面是安全点和锁信息:?
not at a safepoint:正常运行状态
at safepoint:所有线程都因为虚拟机等待状态而阻塞,等待一个虚拟机操作完成
synchronizing:一个特殊的虚拟机操作,要求虚拟机内的其它线程保持等待状态
锁信息为未被线程持有,Mutex是虚拟机内部的锁,而Monitor则是synchronized锁或者其它关联到的Java对象。
堆信息
再下面是堆信息:?
下面的“Card table”表示一种卡表,是jvm维护的一种数据结构,用于记录更改对象时的引用,以便gc时遍历更少的table和root。
本地代码缓存
再下面是本地代码缓存信息:?
编译事件
再下面是本地代码编译信息:?
gc相关记录
再下面是gc执行记录:?
jvm内存映射
再下面是jvm加载的库信息:?
00400000-00401000:内存区域
r-xp:权限,r/w/x/p/s分别表示读/写/执行/私有/共享
00000000:文件内的偏移量
08:02:文件位置的majorID和minorID
39454583:索引节点号
/home/service/jdk1.7.0_55/bin/java:文件位置
jvm启动参数
再下面是jvm启动参数信息:?
服务器信息
再下面是服务器信息:?
转自 http://my.oschina.net/xionghui/blog/498785
相关文章推荐
- Genymotion FAQ
- two eggs
- thinkPHP 数据表的操作
- C#调用百度翻译
- LINUX下常用
- 如何创建和启动一个线程?
- 设计模式学习笔记十九:备忘录模式
- SHUOJ——归并排序——计算思维J题
- OAF学习笔记-16-自定义异常的抛出
- OAF学习笔记-16-自定义异常的抛出
- 自动化脚本自动生成技术探讨
- mybatis 详细入门例子
- Myeclipse 10 使用之修改字体
- 写在前面的话
- OAF学习笔记-16-自定义异常的抛出
- OAF学习笔记-16-自定义异常的抛出
- OAF学习笔记-16-自定义异常的抛出
- OAF学习笔记-16-自定义异常的抛出
- OAF学习笔记-16-自定义异常的抛出
- OAF学习笔记-16-自定义异常的抛出