JVM致命错误日志(hs_err_pid.log)分析
JVM致命错误日志(hs_err_pid.log)分析
当jvm
出现致命错误时,会生成一个错误文件 hs_err_pid<pid>.log
,其中包括了导致jvm crash
的重要信息,可以通过分析该文件定位到导致crash
的根源,从而改善以保证系统稳定。当出现crash
时,该文件默认会生成到工作目录下.
背景
并发线程处理PDF
文件,jvm
出现致命错误时,生成错误文件 hs_err_pid.log。
SIGBUS
意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。
查看hs_err_pid.log
日志
这里一个重要信息是SIGBUS(0x7)
表示jvm crash
时正在执行线程试图访问一块无文件内容对应的内存区域,比如超过文件尾的内存区域,或者以前有文件内容对应,现在为另一进程截断过的内存区域。其中SISBUS
是信号名称,0x7
是信号码,pc=0x00007fa4495592a0
指的是程序计数器的值,pid=34372
是进程号,tid=0x00007fa320cd2700
是线程号。
文件下面是导致crash
的线程信息和该线程栈信息,描述信息如下:
Current thread (0x00007fa348028000): JavaThread "hlooc-task-Orders-9" daemon [_thread_in_vm, id=37394, stack(0x00007fa320bd2000,0x00007fa320cd3000)]
siginfo: si_signo: 7 (SIGBUS), si_code: 2 (BUS_ADRERR), si_addr: 0x00007fa449e29041
以上表示导致出错的线程是0x00007fa348028000
(指针),线程类型是JavaThread
,JavaThread
表示执行的是java
线程,关于该线程其它类型还可能是:
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
后面的hlooc-task-Orders-9
表示线程名,daemon
表示该线程为守护线程,再后面的[_thread_in_vm
表示线程正在执行虚拟机代码,关于该描述其它类型还可能是:
_thread_in_native
:线程当前状态_thread_uninitialized
:线程还没有创建,它只在内存原因崩溃的时候才出现_thread_new
:线程已经被创建,但是还没有启动_thread_in_native
:线程正在执行本地代码,一般这种情况很可能是本地代码有问题_thread_in_vm
:线程正在执行虚拟机代码_thread_in_Java
:线程正在执行解释或者编译后的Java代码_thread_blocked
:线程处于阻塞状态…_trans
:以_trans
结尾,线程正处于要切换到其它状态的中间状态
最后的id=37394
表示线程ID
,stack(0x00007fa320bd2000,0x00007fa320cd3000)
表示栈区间。
siginfo: si_signo: 7 (SIGBUS), si_code: 2 (BUS_ADRERR), si_addr: 0x00007fa449e29041
这部分是导致虚拟机终止的非预期的信号信息:其中si_signo
和si_code
是Linux
下用来鉴别异常的
日志头文件包含概要信息,简述了导致
crash
的原因。而导致crash
的原因很多,常见的原因有jvm
自身的bug
,应用程序错误,jvm
参数配置不当,服务器资源不足,jni
调用错误,线程试图访问一块无文件内容对应的内存区域,比如超过文件尾的内存区域,或者以前有文件内容对应,现在为另一进程截断过的内存区域。
查看liunx
系统日志messages
crash
发生于11:26:33
查看java
业务日志busi.log
11:26:33
处理了两次同一个PDF
文件
结论:线程JavaThread "upp-task-Orders-9"
试图访问的PDF
文件无文件内容对应的内存区域,并发处理有问题.