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
文件無文件內容對應的內存區域,並發處理有問題.