程序在啟動(dòng)或內(nèi)存壓力增加時(shí)出現(xiàn) jvm 崩潰的問題,錯(cuò)誤日志顯示出現(xiàn)了 sigsegv (0xb) 信號(hào),導(dǎo)致進(jìn)程崩潰。我們需要仔細(xì)分析這個(gè)問題的原因,特別是在已經(jīng)排除了軟件問題之后。
根據(jù)提供的 hs_err_pid30391.log 文件,我們可以看到關(guān)鍵信息如下:
- JVM 版本:OpenJDK Runtime Environment Zulu21.40 17-CA (21.0.6 7)
- 錯(cuò)誤類型:SigsEGV (0xb)
- 問題框架:PhaseChaitin::raise_pressure
- 當(dāng)前線程:C2 CompilerThread3
SIGSEGV (Segmentation Violation) 表示程序嘗試訪問內(nèi)存的權(quán)限不足或訪問了不存在的內(nèi)存。這在 JVM 中可能由多個(gè)原因?qū)е?,包括硬件問題、JVM 本身的 bug,或者 JIT(即時(shí)編譯)過程中出現(xiàn)的錯(cuò)誤。
考慮到問題是在更換電源后出現(xiàn),但在遷移到其他機(jī)器上運(yùn)行正常,且在原機(jī)器上的壓力測試無問題,這種情況可能指向以下幾種可能的原因:
- 硬件兼容性問題:盡管壓力測試沒有問題,但在特定負(fù)載下,電源或其他硬件可能與JVM有兼容性問題。
- JVM JIT 編譯問題:JIT 編譯器在特定情況下可能會(huì)導(dǎo)致內(nèi)存訪問錯(cuò)誤,尤其是在高負(fù)載或復(fù)雜的計(jì)算過程中。
基于這些分析和提供的問題答案,我們可以采取以下步驟來進(jìn)一步診斷和解決問題:
禁用 JIT 編譯
首先嘗試禁用 JIT 編譯,看是否能解決問題。可以通過在啟動(dòng)命令中添加以下參數(shù)來實(shí)現(xiàn):
Java -XX:-UseCompiler mohist-1.20.1-cc9de12e-server.jar nogui
如果禁用 JIT 編譯后問題消失,這表明問題可能與 JIT 編譯器有關(guān)。
排除特定方法的 JIT 編譯
如果確實(shí)是 JIT 編譯的問題,可以嘗試排除特定方法的編譯。根據(jù)日志中的信息,可以嘗試排除 java.util.stream.AbstractPipeline 類的所有方法:
java -XX:CompileCommand=exclude,java.util.stream.AbstractPipeline::* mohist-1.20.1-cc9de12e-server.jar nogui
降級(jí) JVM 版本
如果上述方法都不奏效,可以考慮降級(jí) JVM 版本。某些版本的 JVM 可能會(huì)包含導(dǎo)致問題的 bug,通過使用更早的穩(wěn)定版本可能會(huì)解決問題。
在嘗試這些解決方案時(shí),建議在多個(gè)環(huán)境中進(jìn)行測試,以確保問題的解決不僅僅是特定環(huán)境下的偶然現(xiàn)象。同時(shí),保持對(duì) JVM 日志和系統(tǒng)監(jiān)控的關(guān)注,以便在發(fā)生類似問題時(shí)能夠快速定位和解決。