淺談JVM閃崩問(wèn)題定位排查
一、什么是JVM閃崩?
JVM閃崩,指Java進(jìn)程非正常退出,常見(jiàn)現(xiàn)象為進(jìn)程消失、沒(méi)有明顯Java異常、可能生成hs_err_pid*.log或core dump,甚至被 操作系統(tǒng)直接kill。
二、排查思路總覽
- 收集信息:日志、dump文件、系統(tǒng)狀態(tài)。
- 分析JVM日志:重點(diǎn)查看
hs_err_pid*.log。 - 分析系統(tǒng)日志:排查資源耗盡、進(jìn)程被殺等情況。
- 分析core dump:定位native層崩潰。
- 回溯應(yīng)用變更:查找近期變動(dòng)。
- 復(fù)現(xiàn)與隔離:測(cè)試環(huán)境模擬,逐步縮小范圍。
三、詳細(xì)排查步驟
1. 收集關(guān)鍵信息
- JVM錯(cuò)誤日志:
hs_err_pid*.log(一般在工作目錄或/tmp下) - GC日志:如有開(kāi)啟,便于分析內(nèi)存狀況
- 應(yīng)用日志:stdout、stderr、業(yè)務(wù)日志
- 系統(tǒng)日志:
/var/log/messages、dmesg - core dump文件:如有配置,通常在工作目錄或指定路徑
2. 分析hs_err_pid*.log文件
重點(diǎn)關(guān)注以下字段:
| 字段 | 說(shuō)明 |
|---|---|
| Error Signal | 如 SIGSEGV、SIGBUS、SIGFPE、SIGILL,指明崩潰類(lèi)型 |
| Problematic frame | 崩潰發(fā)生的native庫(kù)及函數(shù) |
| Java/Native Stack | 崩潰線程的堆棧,判斷與應(yīng)用代碼還是native庫(kù)有關(guān) |
| Loaded Libraries | 已加載的native庫(kù),排查第三方庫(kù) |
| JVM Version/Args | JVM版本、啟動(dòng)參數(shù),排查已知Bug |
| System Info | 操作系統(tǒng)、CPU架構(gòu)信息 |
舉例:
# A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f8c3b6e1c04, pid=12345, tid=12346 # Problematic frame: # C [libnative.so+0x1c04] crash_func+0x14
- SIGSEGV:段錯(cuò)誤,通常是內(nèi)存非法訪問(wèn)
- libnative.so:第三方native庫(kù)導(dǎo)致崩潰
3. 分析系統(tǒng)日志
查看是否有OOM Killer記錄
grep -i 'kill' /var/log/messages dmesg | grep -i 'oom'
檢查是否有硬件故障、磁盤(pán)異常等
查看進(jìn)程資源限制
ulimit -a
4. 分析core dump(如有)
使用gdb分析
gdb java core (gdb) bt
定位native崩潰堆棧
如果涉及第三方native庫(kù),聯(lián)系庫(kù)廠商或查閱源碼
5. 回溯應(yīng)用變更
- 是否近期升級(jí)JDK、native庫(kù)、調(diào)整JVM參數(shù)
- 是否有新的代碼上線,特別是JNI、Unsafe等操作
- 是否有新部署環(huán)境變更(如容器、虛擬化)
6. 復(fù)現(xiàn)與隔離
- 在測(cè)試環(huán)境重現(xiàn)生產(chǎn)負(fù)載,觀察是否閃崩
- 逐步剔除native庫(kù)、調(diào)整JVM參數(shù),找出觸發(fā)條件
- 通過(guò)壓力測(cè)試、異常輸入等手段復(fù)現(xiàn)問(wèn)題
四、常見(jiàn)JVM閃崩原因
| 原因 | 排查方法 |
|---|---|
| native庫(kù)(JNI)異常 | hs_err_pid*.log顯示崩潰在第三方庫(kù),隔離/升級(jí)該庫(kù) |
| 系統(tǒng)OOM | 系統(tǒng)日志有OOM記錄,JVM被kill,優(yōu)化內(nèi)存參數(shù) |
| JVM自身Bug | 查閱JVM版本、已知Bug,升級(jí)JDK |
| 資源限制(ulimit) | 文件句柄、線程數(shù)超限,調(diào)整ulimit |
| 硬件故障 | 系統(tǒng)日志有硬件報(bào)錯(cuò),聯(lián)系運(yùn)維排查硬件 |
| 容器/虛擬化環(huán)境限制 | 容器資源配置不足,調(diào)整容器參數(shù) |
五、典型案例分析
案例1:native庫(kù)內(nèi)存越界
- 問(wèn)題表現(xiàn):
hs_err_pid*.log顯示SIGSEGV,問(wèn)題幀為第三方庫(kù) - 處理:升級(jí)或隔離該庫(kù),或聯(lián)系廠商修復(fù)
案例2:系統(tǒng)OOM
- 問(wèn)題表現(xiàn):進(jìn)程無(wú)異常日志,系統(tǒng)日志顯示OOM killer kill進(jìn)程
- 處理:優(yōu)化JVM-Xmx參數(shù),提升機(jī)器內(nèi)存或限制其他進(jìn)程
案例3:JVM版本Bug
- 問(wèn)題表現(xiàn):
hs_err_pid*.log顯示崩潰在JVM自身代碼 - 處理:查閱JDK發(fā)行說(shuō)明,升級(jí)到穩(wěn)定版本
六、實(shí)用排查命令和工具
查找錯(cuò)誤日志
find / -name "hs_err_pid*.log"
查看崩潰信號(hào)和問(wèn)題幀
grep -E 'SIG|Problematic frame' hs_err_pid*.log
查看ulimit
ulimit -a
分析core dump
gdb java core
七、預(yù)防與建議
- 使用穩(wěn)定JDK版本,及時(shí)升級(jí)修復(fù)已知Bug
- native庫(kù)充分測(cè)試,避免自定義或不成熟庫(kù)
- 合理配置JVM參數(shù),避免資源超限
- 開(kāi)啟監(jiān)控與報(bào)警,及時(shí)發(fā)現(xiàn)異常
- 配置core dump和heap dump,便于事后分析
- 灰度發(fā)布/回滾機(jī)制,新版本優(yōu)先小流量測(cè)試
八、快速定位流程圖
flowchart TD
A[JVM閃崩] --> B{是否有hs_err_pid*.log}
B -- 有 --> C[分析日志]
B -- 無(wú) --> D[查系統(tǒng)日志]
C --> E{native庫(kù)/系統(tǒng)資源/JVM自身}
D --> E
E --> F[定位原因]
F --> G[修復(fù)/優(yōu)化/升級(jí)]
九、如需幫助
如有具體hs_err_pid*.log內(nèi)容、core dump信息、系統(tǒng)日志片段,可貼出來(lái),我可以幫你進(jìn)一步分析定位!
十、深入分析技巧
1.hs_err_pid.log 關(guān)鍵字段詳解*
異常信號(hào)(例如 SIGSEGV)
SIGSEGV:段錯(cuò)誤,通常是非法內(nèi)存訪問(wèn)。SIGBUS:總線錯(cuò)誤,可能是硬件或內(nèi)存映射問(wèn)題。SIGFPE:浮點(diǎn)運(yùn)算異常,如除零。SIGILL:非法指令,通常是JVM或native庫(kù)損壞。
Problematic frame
直接定位到崩潰的native方法或庫(kù)。例如:
Problematic frame: C [libnative.so+0x1c04] crash_func+0x14
如果是 JVM 自身的代碼(如 hotspot),建議查閱對(duì)應(yīng)版本的已知Bug。
線程堆棧(Thread stack)
- 可以分析崩潰發(fā)生前的線程狀態(tài),判斷是否與業(yè)務(wù)代碼有關(guān)。
Loaded Libraries
- 列出所有已加載的native庫(kù),排查是否有未授權(quán)或不穩(wěn)定的庫(kù)。
JVM參數(shù)
- 例如
-Xmx、-XX:MaxDirectMemorySize等,判斷是否資源配置合理。
2.core dump 深度分析
使用 gdb 查看 native 層堆棧
gdb java core (gdb) bt
如果涉及第三方庫(kù),建議聯(lián)系廠商或查閱源碼。
可配合 JVM 的 -XX:OnError 參數(shù),在崩潰時(shí)自動(dòng)執(zhí)行腳本收集更多信息。
3.分析GC日志
- 判斷是否頻繁Full GC,是否有內(nèi)存泄漏或資源耗盡導(dǎo)致JVM異常退出。
- 關(guān)注
OutOfMemoryError、Promotion failed等異常。
4.操作系統(tǒng)資源分析
- 查看進(jìn)程資源限制(ulimit),如文件句柄、線程數(shù)。
- 檢查系統(tǒng)負(fù)載、內(nèi)存、swap等,是否有其他進(jìn)程影響。
十一、團(tuán)隊(duì)協(xié)作流程建議
- 建立故障應(yīng)急群組:運(yùn)維、開(kāi)發(fā)、測(cè)試、架構(gòu)師等多方協(xié)同。
- 故障分級(jí)響應(yīng):根據(jù)影響范圍,制定不同等級(jí)響應(yīng)流程。
- 標(biāo)準(zhǔn)化信息收集腳本:如自動(dòng)打包
hs_err_pid*.log、core dump、系統(tǒng)日志等。 - 定期復(fù)盤(pán):每次閃崩后,團(tuán)隊(duì)復(fù)盤(pán)總結(jié),完善預(yù)案和文檔。
十二、典型問(wèn)題場(chǎng)景與處理建議
場(chǎng)景1:頻繁閃崩但日志無(wú)明顯異常
- 可能是JVM參數(shù)配置不合理(如直接內(nèi)存過(guò)大)。
- 建議逐步縮減參數(shù),或開(kāi)啟更多JVM診斷參數(shù)(如
-XX:+PrintFlagsFinal)。
場(chǎng)景2:升級(jí)JDK后出現(xiàn)閃崩
- 查看JDK發(fā)行說(shuō)明,確認(rèn)是否有兼容性問(wèn)題。
- 回退到原版本對(duì)比,或升級(jí)到更高版本。
場(chǎng)景3:業(yè)務(wù)代碼近期引入JNI/Unsafe
- 回溯代碼變更,重點(diǎn)審查native相關(guān)調(diào)用。
- 通過(guò)代碼審查、單元測(cè)試、壓力測(cè)試等方式排查。
場(chǎng)景4:容器環(huán)境JVM閃崩
- 容器設(shè)置的資源限制(如memory、cpu)過(guò)低,導(dǎo)致JVM被kill。
- 檢查容器配置,合理調(diào)高資源限制。
十三、常用JVM診斷參數(shù)
-XX:+HeapDumpOnOutOfMemoryError:OOM時(shí)自動(dòng)生成heap dump。-XX:+PrintGCDetails -Xloggc:<file>:輸出詳細(xì)GC日志。-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=20M:GC日志滾動(dòng)。-XX:OnError="sh collect_info.sh":崩潰時(shí)自動(dòng)執(zhí)行收集腳本。
十四、自動(dòng)化故障信息收集腳本示例
#!/bin/bash
# collect_info.sh
date > info.txt
echo "==== hs_err_pid logs ====" >> info.txt
find / -name "hs_err_pid*.log" -exec cat {} \; >> info.txt
echo "==== dmesg ====" >> info.txt
dmesg | tail -n 100 >> info.txt
echo "==== ulimit ====" >> info.txt
ulimit -a >> info.txt
echo "==== top ====" >> info.txt
top -b -n 1 >> info.txt
tar czf jvm_crash_info_$(date +%s).tar.gz info.txt將此腳本配置到JVM參數(shù)-XX:OnError="sh /path/collect_info.sh",崩潰時(shí)自動(dòng)收集關(guān)鍵信息。
十五、總結(jié)與建議
JVM閃崩排查需要多維度分析,重在收集關(guān)鍵信息、分析日志、定位native層、結(jié)合系統(tǒng)資源與應(yīng)用變更。建議建立標(biāo)準(zhǔn)化排查流程,提升故障響應(yīng)效率。
- JVM閃崩排查重在信息收集與多層分析,建議建立標(biāo)準(zhǔn)化流程。
- 重點(diǎn)關(guān)注
hs_err_pid*.log、系統(tǒng)資源、native庫(kù)變更、JVM參數(shù)、容器/虛擬化環(huán)境。 - 建議團(tuán)隊(duì)協(xié)作、自動(dòng)化收集、定期復(fù)盤(pán),持續(xù)優(yōu)化故障處理能力。
- 如遇疑難問(wèn)題,及時(shí)尋求JDK廠商、社區(qū)或第三方庫(kù)支持。
到此這篇關(guān)于淺談JVM閃崩問(wèn)題定位排查的文章就介紹到這了,更多相關(guān)JVM閃崩內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java多線程 ReentrantReadWriteLock原理及實(shí)例詳解
這篇文章主要介紹了Java多線程 ReentrantReadWriteLock原理及實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
java正則表達(dá)式實(shí)現(xiàn)提取需要的字符并放入數(shù)組【ArrayList數(shù)組去重復(fù)功能】
這篇文章主要介紹了java正則表達(dá)式實(shí)現(xiàn)提取需要的字符并放入數(shù)組,即基于正則的ArrayList數(shù)組去重復(fù)功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01
Java設(shè)計(jì)模式之單一職責(zé)原則精解
設(shè)計(jì)模式(Design pattern)代表了最佳的實(shí)踐,通常被有經(jīng)驗(yàn)的面向?qū)ο蟮能浖_(kāi)發(fā)人員所采用。設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案。本篇介紹設(shè)計(jì)模式七大原則之一的單一職責(zé)原則2022-02-02
SpringBoot如何讀取application.properties配置文件
這篇文章主要介紹了SpringBoot如何讀取application.properties配置文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
用IntelliJ IDEA看Java類(lèi)圖的方法(圖文)
這篇文章主要介紹了用IntelliJ IDEA看Java類(lèi)圖的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
SpringCloud使用Feign實(shí)現(xiàn)遠(yuǎn)程調(diào)用流程詳細(xì)介紹
OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡(luò)通信的細(xì)節(jié),直接面向接口的方式開(kāi)發(fā),讓開(kāi)發(fā)者感知不到網(wǎng)絡(luò)通信細(xì)節(jié)。所有遠(yuǎn)程調(diào)用,都像調(diào)用本地方法一樣完成2023-02-02

