JVM致命錯誤日誌(hs_err_pid.log)分析
致命錯誤出現的時候,JVM 生成了 hs_err_pid<pid>.log 這樣的檔案,其中往往包含了虛擬機器崩潰原因的重要資訊。因為經常遇到,在這篇文章裡,我挑選了一個,並且逐段分析它包含的內容(檔案可以在文章最後下載)。預設情況下檔案是建立在工作目錄下的(如果沒許可權建立的話 JVM 會嘗試把檔案寫到/tmp 這樣的臨時目錄下面去),當然,檔案格式和路徑也可以通過引數指定,比如:
1 |
|
這個檔案將包括:
- 觸發致命錯誤的操作異常或者訊號;
- 版本和配置資訊;
- 觸發致命異常的執行緒詳細資訊和執行緒棧;
- 當前執行的執行緒列表和它們的狀態;
- 堆的總括資訊;
- 載入的本地庫;
- 命令列引數;
- 環境變數;
- 作業系統 CPU 的詳細資訊。
首先,看到的是對問題的概要介紹:
1 |
|
一個非預期的錯誤被 JRE 檢測到,其中:
- SIGSEGV 是訊號名稱
- 0xb 是訊號碼
- pc=0x03568cf4 指的是程式計數器的值
- pid=16819 是程式號
- tid=3073346448 是執行緒號
如果你對 JVM 有了解,應該不會對這些東西陌生。
接下來是 JRE 和 JVM 的版本資訊:
1 2 3 |
|
執行在 mixed 模式下。
然後是問題幀的資訊:
1 2 3 |
|
- C:幀型別為本地幀,幀的型別包括:
- C:本地 C 幀
- j:解釋的 Java 幀
- V:虛擬機器幀
- v:虛擬機器生成的存根棧幀
- J:其他幀型別,包括編譯後的 Java 幀
- libgtk-x11-2.0.so.0+0x19fcf4:和程式計數器(pc)表達的含義一樣,但是用的是本地 so 庫+偏移量的方式。
接下去第一部分是執行緒資訊:
1 |
|
當前執行緒的:
- 0x09f30c00:指標
- JavaThread:執行緒型別,可能的型別包括:
- JavaThread
- VMThread
- CompilerThread
- GCTaskThread
- WatcherThread
- ConcurrentMarkSweepThread
- main:名字
- _thread_in_native:執行緒當前狀態,狀態列舉包括:
- _thread_uninitialized:執行緒還沒有建立,它只在記憶體原因崩潰的時候才出現
- _thread_new:執行緒已經被建立,但是還沒有啟動
- _thread_in_native:執行緒正在執行原生程式碼,一般這種情況很可能是原生程式碼有問題
- _thread_in_vm:執行緒正在執行虛擬機器程式碼
- _thread_in_Java:執行緒正在執行解釋或者編譯後的 Java 程式碼
- _thread_blocked:執行緒處於阻塞狀態
- …_trans:以_trans 結尾,執行緒正處於要切換到其它狀態的中間狀態
- id=16822:執行緒 ID
- 0xb72a8000,0xb72f9000:棧區間
1 |
|
這部分是導致虛擬機器終止的非預期的訊號資訊,含義前面已經大致提到過了。其中 si_errno 和 si_code 是 Linux 下用來鑑別異常的,Windows 下是一個 ExceptionCode。
1 2 3 |
|
這是暫存器上下文。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
棧頂程式計數器旁的操作碼,它們可以被反彙編成系統崩潰前執行的指令。
1 2 3 4 5 6 7 8 9 10 |
|
暫存器和記憶體對映資訊。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
執行緒棧。包含了地址、棧頂、棧計數器和執行緒尚未使用的棧資訊,由於棧可能非常長,列印的長度有限制,但是至少本地棧和 Java 棧都列印出來了(很多時候本地棧列印不出來,但是 Java 棧一般都能列印出來)。從中可以看到,Eclipse 的虛擬機器崩潰了。
1 2 3 4 |
|
執行緒資訊。一目瞭然,不解釋了。
1 |
|
虛擬機器狀態。包括:
- not at a safepoint:正常執行狀態;
- at safepoint:所有執行緒都因為虛擬機器等待狀態而阻塞,等待一個虛擬機器操作完成;
- synchronizing:一個特殊的虛擬機器操作,要求虛擬機器內的其它執行緒保持等待狀態。
1 |
|
虛擬機器的 Mutex 和 Monitor 目前沒有被執行緒持有。Mutex 是虛擬機器內部的鎖,而 Monitor 則關聯到了 Java 物件。
1 2 3 4 5 6 7 8 9 |
|
堆資訊。新生代、老生代、永久代。對 JVM 有了解的人應該都清楚,不解釋了。
1 2 |
|
程式碼快取(Code Cache)。這是一塊用於編譯和儲存原生程式碼的記憶體,注意是原生程式碼,它和 PermGen(永久代)是不一樣的,永久帶是用來存放 Java 類定義的。
1 2 3 4 5 6 |
|
記憶體對映。這些資訊是虛擬機器崩潰時的虛擬記憶體列表區域。在定位崩潰原因的時候,它可以告訴你哪些類庫正在被使用,位置在哪裡,還有堆疊和守護頁資訊。就以列表中第一條為例說明:
- 00101000-00122000:記憶體區域
- r-xp:許可權,r/w/x/p/s 分別表示讀/寫/執行/私有/共享
- 00000000:檔案內的偏移量
- 08:01:檔案位置的 majorID 和 minorID
- 3483560:索引節點號
- /usr/lib/libjpeg.so.62.0.0:檔案位置
每一個 lib 都有兩塊虛擬記憶體區域—— 程式碼和資料,它們的許可權不同,程式碼區域是 r-xp;資料區域是 rwxp。守護頁(guard page)由許可權為–xp 和 rwxp 的一對組成。
1 2 3 4 5 6 7 8 |
|
虛擬機器引數和環境變數。
1 2 3 4 |
|
訊號控制程式碼。對於 Linux 下的訊號機制,參閱 wiki 百科, 連結 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
系統資訊。
感謝您的關注!可加QQ1群:135430763,QQ2群:454796847,QQ3群:187424846。QQ群進群密碼:xttblog,想加微信群的朋友,可以微信搜尋:xmtxtt,備註:“xttblog”,新增助理微信拉你進群。備註錯誤不會同意好友申請。再次感謝您的關注!後續有精彩內容會第一時間發給您!原創文章投稿請傳送至532009913@qq.com郵箱。商務合作可新增助理微信進行溝通!
相關文章
- JVM致命錯誤日誌(hs_err_pid.log)解讀JVM
- net 日誌分析錯誤
- mysql 日誌之錯誤日誌MySql
- 排查錯誤日誌
- mysql慢查詢和錯誤日誌分析MySql
- Apche日誌系列(2):錯誤日誌(轉)
- alert日誌中的兩種ORA錯誤分析
- Mabatis配置錯誤日誌BAT
- 日誌查詢錯誤
- 錯誤日誌檢視
- SQL Server 錯誤日誌SQLServer
- 如何用NodeJS讀取分析Nginx錯誤日誌NodeJSNginx
- log4j不輸出日誌錯誤分析
- MySQL 狂寫錯誤日誌MySql
- jdon框架日誌資訊錯誤框架
- SAP 錯誤日誌的調查
- node錯誤處理與日誌
- 上一個日誌的錯誤
- Sqlserver:代理錯誤日誌,知多少?SQLServer
- SQL Server ErrorLog 錯誤日誌SQLServerError
- aix ip 衝突錯誤日誌AI
- oracle日誌錯誤恢復(轉)Oracle
- insert中啟用錯誤日誌的問題及分析
- mysql之 日誌體系(錯誤日誌、查詢日誌、二進位制日誌、事務日誌、中繼日誌)MySql中繼
- 開啟PHP的錯誤log日誌PHP
- 常見的錯誤日誌型別型別
- 日誌分析-apache日誌分析Apache
- JVM GC日誌解析JVMGC
- JVM的GC日誌JVMGC
- Mysql5.7 的錯誤日誌中最常見的note日誌MySql
- MySQL資料庫中的日誌檔案---(1)錯誤日誌MySql資料庫
- Kubelet 錯誤日誌 broken pipe 和 connection reset by peer 的原因分析
- 通過JVM日誌來進行安全點分析JVM
- ITMySQL錯誤日誌與通用查詢日誌圖文詳析jugMySql
- node專案錯誤處理與日誌
- 2、MySQL錯誤日誌(Error Log)詳解MySqlError
- Oracle10g DML錯誤日誌表Oracle
- JVM GC 日誌詳解JVMGC