JVM致命錯(cuò)誤日志詳解(最新推薦)
最近一段時(shí)間生產(chǎn)環(huán)境頻繁出問題,每次都會(huì)生成一個(gè)hs_err_pid*.log文件,因?yàn)楣ぷ鲀?nèi)容的原因,在此之前并沒有了解過相關(guān)內(nèi)容,趁此機(jī)會(huì)學(xué)習(xí)下,根據(jù)項(xiàng)目的使用情況,此文章針對(duì)JDK 8進(jìn)行分析,不過因?yàn)樗夭膯栴},文章中引用的文件內(nèi)容為JDK 7生成的文件,此處應(yīng)該不影響,因?yàn)楣俜轿臋n中關(guān)于此部分說(shuō)明使用的是JDK 6生成的文件。我們將按照內(nèi)容在文件中出現(xiàn)的順序進(jìn)行介紹。本人水平有限,工作中也沒有太多機(jī)會(huì)進(jìn)行此類知識(shí)的應(yīng)用,文章內(nèi)容主要參考官方文檔,某些內(nèi)容在官方文檔中并沒有涉及,相應(yīng)的介紹也不一定準(zhǔn)確,如果有不同看法可在評(píng)論區(qū)留言交流。
PS:本人水平有限,工作中也沒有太多機(jī)會(huì)進(jìn)行此類知識(shí)的應(yīng)用,文章內(nèi)容絕大多數(shù)來(lái)自于官方文檔,某些內(nèi)容在官網(wǎng)中并沒有涉及,相應(yīng)的介紹不一定準(zhǔn)確,希望各位大佬不吝賜教
JDK 8
官方文檔下載地址:https://www.oracle.com/java/technologies/javase-jdk8-doc-downloads.html致命錯(cuò)誤日志文檔:/docs/technotes/guides/troubleshoot/felog.html#fatal_error_log_vm
JDK 7
官方文檔地址:https://docs.oracle.com/javase/7/docs/致命錯(cuò)誤日志文檔:https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/felog.html
文件描述
錯(cuò)誤日志是在JVM遇到致命錯(cuò)誤時(shí)生成的日志文件,可能包括以下信息:
- 引發(fā)致命錯(cuò)誤的異常操作或信號(hào)
- 版本和配置信息
- 引發(fā)致命錯(cuò)誤的線程詳細(xì)信息和線程堆棧記錄
- 正在運(yùn)行的線程及其狀態(tài)的列表
- 有關(guān)堆的概要信息
- 加載的本機(jī)庫(kù)的列表
- 命令行參數(shù)
- 環(huán)境變量
- 操作系統(tǒng)和 CPU 的詳細(xì)信息
當(dāng)問題嚴(yán)重到錯(cuò)誤處理器無(wú)法收集并報(bào)告所有信息時(shí),可能只有一部分信息會(huì)寫入錯(cuò)誤日志。
文件總共分為一下幾個(gè)章節(jié):
- 簡(jiǎn)單描述崩潰信息的文件頭
- 線程描述部分
- 進(jìn)程描述部分
- 系統(tǒng)信息部分
文件位置
致命錯(cuò)誤日志文件位置可以通過 -XX:ErrorFile
進(jìn)行指定,例如:
java * -XX:ErrorFile=/var/log/java/java_error%p.log
以上設(shè)置表示文件會(huì)放在/var/log/java
目錄下,%p
表示進(jìn)程的PID。如果不設(shè)置XX:ErrorFile
屬性,日志默認(rèn)生成在執(zhí)行java命令的目錄下,文件名默認(rèn)為hs_err_pid%p.log
,如果該目錄因?yàn)槟撤N情況無(wú)法寫入(空間不足,權(quán)限不足等),在linux系統(tǒng)下默認(rèn)寫到/tmp
目錄下,windows系統(tǒng)下默認(rèn)使用環(huán)境變量中TMP
對(duì)應(yīng)的目錄,如果沒有則使用TEMP
對(duì)應(yīng)的目錄(TMP和TEMP均為windows默認(rèn)的環(huán)境變量,且默認(rèn)值一樣)。
文件頭
文件頭在錯(cuò)誤日志的最開頭,主要是對(duì)問題的簡(jiǎn)單描述。這部分內(nèi)容同樣會(huì)打印到標(biāo)準(zhǔn)輸出,可能也會(huì)打印到應(yīng)用程序的控制臺(tái)上。示例如下:
# # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f80e0cd095c, pid=48, tid=140189843019520 # # JRE version: Java(TM) SE Runtime Environment (7.0_80-b15) (build 1.7.0_80-b15) # Java VM: Java HotSpot(TM) 64-Bit Server VM (24.80-b11 mixed mode linux-amd64 compressed oops) # Problematic frame: # V [libjvm.so+0x65395c] jni_SetByteArrayRegion+0x19c # # Core dump written. Default location: /apps/gateway/project/bin/core or core.48 # # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp #
錯(cuò)誤信息記錄
前兩行主要描述了信號(hào)類型、發(fā)起信號(hào)的程序計(jì)數(shù)器、進(jìn)程ID和線程ID,對(duì)應(yīng)關(guān)系如下所示,鑒于瀏覽器和手機(jī)端顯示效果不一致,此處提供兩種方式:
# SIGSEGV (0xb) at pc=0x00007f80e0cd095c, pid=48, tid=140189843019520 | | | | | | | | | +--- 線程ID | | | +----------- 進(jìn)程ID | | +-------------------------------- 程序計(jì)數(shù)器對(duì)應(yīng)的指針 | +-------------------------------------------- 信號(hào)值(十六進(jìn)制) +--------------------------------------------------- 信號(hào)名稱
?日志內(nèi)容 | 實(shí)際含義 |
---|---|
SIGSEGV | 信號(hào)名稱 |
(0xb) | 信號(hào)值(十六進(jìn)制) |
pc=0x00007f80e0cd095c | 程序計(jì)數(shù)器對(duì)應(yīng)的指針 |
pid=48 | 進(jìn)程ID |
tid=140189843019520 | 線程ID |
信號(hào)名稱是操作系統(tǒng)自身的一種信息,CentOS 7下共有以下35種,可在/usr/include/bits/signum.h中查看其具體的聲明
信號(hào)名稱 | 信號(hào)值 | 含義 |
---|---|---|
SIGHUP | 1 | Hangup (POSIX). |
SIGINT | 2 | Interrupt (ANSI). |
SIGQUIT | 3 | Quit (POSIX). |
SIGILL | 4 | Illegal instruction (ANSI). |
SIGTRAP | 5 | Trace trap (POSIX). |
SIGABRT | 6 | Abort (ANSI). |
SIGIOT | 6 | IOT trap (4.2 BSD). |
SIGBUS | 7 | BUS error (4.2 BSD). |
SIGFPE | 8 | Floating-point exception (ANSI). |
SIGKILL | 9 | Kill, unblockable (POSIX). |
SIGUSR1 | 10 | User-defined signal 1 (POSIX). |
SIGSEGV | 11 | Segmentation violation (ANSI). |
SIGUSR2 | 12 | User-defined signal 2 (POSIX). |
SIGPIPE | 13 | Broken pipe (POSIX). |
SIGALRM | 14 | Alarm clock (POSIX). |
SIGTERM | 15 | Termination (ANSI). |
SIGSTKFLT | 16 | Stack fault. |
SIGCLD | SIGCHLD | Same as SIGCHLD (System V). |
SIGCHLD | 17 | Child status has changed (POSIX). |
SIGCONT | 18 | Continue (POSIX). |
SIGSTOP | 19 | Stop, unblockable (POSIX). |
SIGTSTP | 20 | Keyboard stop (POSIX). |
SIGTTIN | 21 | Background read from tty (POSIX). |
SIGTTOU | 22 | Background write to tty (POSIX). |
SIGURG | 23 | Urgent condition on socket (4.2 BSD). |
SIGXCPU | 24 | CPU limit exceeded (4.2 BSD). |
SIGXFSZ | 25 | File size limit exceeded (4.2 BSD). |
SIGVTALRM | 26 | Virtual alarm clock (4.2 BSD). |
SIGPROF | 27 | Profiling alarm clock (4.2 BSD). |
SIGWINCH | 28 | Window size change (4.3 BSD, Sun). |
SIGPOLL | SIGIO | Pollable event occurred (System V). |
SIGIO | 29 | I/O now possible (4.2 BSD). |
SIGPWR | 30 | Power failure restart (System V). |
SIGSYS | 31 | Bad system call. |
SIGUNUSED | 31 | - |
JVM運(yùn)行信息
接下來(lái)兩行描述了JVM相關(guān)版本信息及運(yùn)行配置信息,內(nèi)容如下:
# JRE version: Java(TM) SE Runtime Environment (7.0_80-b15) (build 1.7.0_80-b15) # Java VM: Java HotSpot(TM) 64-Bit Server VM (24.80-b11 mixed mode linux-amd64 compressed oops)
上述文件內(nèi)容可以得知以下幾點(diǎn):
- JRE版本號(hào)為1.7u80
- JVM版本號(hào)為24.80-b11
- JVM運(yùn)行在Server模式下。對(duì)應(yīng)的是Client模式,Client JVM適合需要快速啟動(dòng)和較小內(nèi)存空間的應(yīng)用,它適合交互性的應(yīng)用,比如GUI;而Server JVM則是看重執(zhí)行效率的應(yīng)用的最佳選擇,更適合服務(wù)端應(yīng)用。
- JVM運(yùn)行在混合模式下,即mixed mode,是JVM默認(rèn)的運(yùn)行模式。其他模式還有解釋模式(interpreted mode)和編譯模式(compiled mode),解釋模式會(huì)強(qiáng)制JVM以解釋方式執(zhí)行所有的字節(jié)碼,編譯模式下JVM在第一次使用時(shí)會(huì)把所有的字節(jié)碼編譯成本地代碼,這兩種模式各有優(yōu)劣,單獨(dú)使用時(shí)都會(huì)有部分性能上的損失,所以默認(rèn)使用混合模式即可,混合模式下對(duì)于字節(jié)碼中多次被調(diào)用的部分,JVM會(huì)將其編譯成本地代碼以提高執(zhí)行效率;而被調(diào)用很少(甚至只有一次)的方法在解釋模式下會(huì)繼續(xù)執(zhí)行,從而減少編譯和優(yōu)化成本。
崩潰原因
接下來(lái)兩行描述了引發(fā)崩潰問題的函數(shù)幀
# Problematic frame: # V [libjvm.so+0x65395c] jni_SetByteArrayRegion+0x19c | | | +-- 類似于程序計(jì)數(shù)器, 以庫(kù)名和偏移量表示。 | 對(duì)于與位置無(wú)關(guān)的庫(kù)(JVM和其他庫(kù)),可以不通過 | 調(diào)試器或通過反匯編程序轉(zhuǎn)存偏移量周圍結(jié) | 構(gòu)的core文件來(lái)定位引起崩潰的指令。 +----------------- 幀類型
幀類型包括以下幾種:
幀類型 | 描述 |
---|---|
C | Native C frame |
j | Interpreted Java frame |
V | VMframe |
v | VMgenerated stub frame |
J | Other frame types, including compiled Java frames |
關(guān)于例子中描述的jni_SetByteArrayRegion+0x19c
這部分目前沒有找到相關(guān)的資料,官方給的示例中并沒有這一部分,根據(jù)字面含義來(lái)看,此部分應(yīng)該表示的是崩潰時(shí)正在通過JNI方式調(diào)用SetByteArrayRegion方法。
錯(cuò)誤信息
接下來(lái)的錯(cuò)誤信息部分根據(jù)不同錯(cuò)誤顯示不一樣的內(nèi)容,在官方給的資料中提供了一份關(guān)于內(nèi)部錯(cuò)誤的錯(cuò)誤信息,示例如下:
# An unexpected error has been detected by HotSpot Virtual Machine: # Internal Error (4F533F4C494E55583F491418160E43505000F5), pid=10226, tid=16384 # Java VM: Java HotSpot(TM) Client VM (1.6.0-rc-b63 mixed mode)
以上示例中提供的內(nèi)容沒有信號(hào)名稱和信號(hào)值,只包含了Internal Error
和一個(gè)十六進(jìn)制的字符串,該字符串對(duì)出現(xiàn)問題的模塊和行號(hào)進(jìn)行了編碼,通常情況下只對(duì)JVM工程師有用。
因?yàn)槲覀兩a(chǎn)環(huán)境上出現(xiàn)的問題和示例中的問題種類不一樣,所以我們拿到了這樣一段信息:
# Core dump written. Default location: /apps/gateway/project/bin/core or core.48 # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp
這段信息中記錄了core dump文件的位置和官方的BUG反饋?lái)?yè)面地址,針對(duì)具體問題則需要查看core dump文件了。
線程描述
這一部分描述崩潰時(shí)正在運(yùn)行的線程信息,如果有多個(gè)線程同時(shí)崩潰,只會(huì)打印其中一個(gè)線程的信息。
線程信息
Current thread (0x00007f80dc8ce000): JavaThread "RcvThread: com.*.*.*.remote.internal.RemoteTCPConnection[qmid=*,fap=10,peer=/*.*.*.9,localport=*,ssl=no]" daemon [_thread_in_native_trans, id=90,stack(0x00007f807dbb5000,0x00007f807dcb6000)]
第一部分展示了引發(fā)致命錯(cuò)誤的線程,以上為生產(chǎn)的實(shí)際信息,因?yàn)槊舾行畔?,?nèi)容中部分字段使用*
進(jìn)行了脫敏。各部分說(shuō)明如下:
?日志內(nèi)容 | 實(shí)際含義 |
---|---|
(0x0805ac88) | 指針地址 |
JavaThread | 線程類型 |
main | 線程方法名 |
_thread_in_native | 線程狀態(tài) |
id=21139 | 線程ID |
stack(0x7dbb5000, 0x7dcb6000) | 棧區(qū)間 |
Current thread (0x0805ac88): JavaThread "main" [_thread_in_native, id=21139, stack(0x7dbb5000, 0x7dcb6000)] | | | | | | | | | | | +--------- 棧區(qū)間 | | | | +---------------------- ID | | | +--------------------------------- 狀態(tài) | | +---------------------------------------------- 名稱 | +-------------------------------------------------------- 類型 +---------------------------------------------------------------------- 指針
線程指針指的是JVM內(nèi)部的線程結(jié)構(gòu),一般只在實(shí)時(shí)調(diào)試JVM或core文件時(shí)才會(huì)有用。線程類型包括以下幾種:
JavaThread
VMThread
CompilerThread
GCTaskThread
WatcherThread
ConcurrentMarkSweepThread
部分進(jìn)程可能包含daemon
標(biāo)識(shí),表示該進(jìn)程為守護(hù)進(jìn)程,該項(xiàng)不一定會(huì)存在。
接下來(lái)的線程狀態(tài)中常見的有以下幾種:
Thread State | Description |
---|---|
_thread_uninitialized | 線程未創(chuàng)建,僅在內(nèi)存崩潰時(shí)出現(xiàn)。 |
_thread_new | 線程已被創(chuàng)建,但是沒有啟動(dòng)。 |
_thread_in_native | 線程正在執(zhí)行本地代碼,可能因?yàn)楸镜卮a的BUG導(dǎo)致此問題。 |
_thread_in_vm | 線程正在執(zhí)行虛擬機(jī)代碼。 |
_thread_in_Java | 線程正在執(zhí)行編譯或解釋后的Java代碼。 |
_thread_blocked | 線程被阻塞。 |
..._trans | 以上狀態(tài)如果后邊帶有_trans ,表示線程正在切換狀態(tài)。 |
信號(hào)信息
siginfo:si_signo=SIGSEGV: si_errno=0, si_code=0 (SEGV0), si_addr=0x0000000000000000
信號(hào)信息描述了導(dǎo)致JVM終止的異常信號(hào)信息,此部分信息根據(jù)操作系統(tǒng)不同會(huì)有所區(qū)別,上邊的例子是linux服務(wù)器下生成的內(nèi)容,在windows下內(nèi)容如下:
siginfo: ExceptionCode=0xc0000005, reading address 0xd8ffecf1 | | | +--------- 線程異常時(shí)讀取的地址 +------------------------------------ 異常碼
計(jì)數(shù)器信息
Registers: RAX=0x00007f80e2109e00, RBX=0x00007f80dc8ce000, RCX=0x0000000000001a70, RDX=0x00007f80e14c87f0 RSP=0x00007f807dca4710, RBP=0x00007f807dca4780, RSI=0x00007f807dcb47f8, RDI=0x00007f80dc8ce1e8 R8 =0x00007f807dca47a0, R9 =0x000000000000005a, R10=0x0000000000000000, R11=0x0000000000000000 R12=0x00007f807dcb47f8, R13=0x0000000000001a70, R14=0x0000000000000000, R15=0x00007f80e14c8800 RIP=0x00007f80e0cd095c, EFLAGS=0x0000000000010206, CSGSFS=0xffff000000000033, ERR=0x0000000000000007 TRAPNO=0x000000000000000e
此部分內(nèi)容為程序崩潰時(shí)程序計(jì)數(shù)器中的內(nèi)容,這一部分的打印格式和服務(wù)器的處理器類型有關(guān),以上為我手中文件的內(nèi)容,這一部分內(nèi)容與下一部分結(jié)合來(lái)看會(huì)比較有用(實(shí)際上也沒看懂)。
機(jī)器指令
Top of Stack: (sp=0x00007f807dca4710) 0x00007f807dca4710: 0000000000007ffe 00007f807dca47a0 0x00007f807dca4720: 00007f807dcb5700 00007f807dcb5680 ...... 0x00007f807dca48f0: 2020202020202020 2020202020202020 0x00007f807dca4900: 2020202020202020 1c00000020202020 Instructions: (pc=0x00007f80e0cd095c) 0x00007f80e0cd093c: ff 0f 1f 00 48 8b 05 59 b3 7b 00 48 89 da 48 c1 0x00007f80e0cd094c: ea 04 8b 00 21 d0 48 8b 15 cf 6f 7b 00 48 03 02 0x00007f80e0cd095c: c7 00 01 00 00 00 e9 b6 fe ff ff 66 0f 1f 84 00 0x00007f80e0cd096c: 00 00 00 00 45 85 ed 74 40 84 c9 74 77 48 8b 05
以上是博主文件的內(nèi)容,因?yàn)槠蛑虚g部分隱藏了,這一部分內(nèi)容包含了系統(tǒng)崩潰時(shí)程序計(jì)數(shù)器棧頂?shù)?2個(gè)指令。這些信息可以通過反編譯程序編譯出崩潰地址附近的指令。需要注意的是A32和AMD64架構(gòu)的指令長(zhǎng)度不一致,所以并不一定能夠反編譯出這部分指令。
內(nèi)存映射信息
Register to memory mapping: RAX=0x00007f80e2109e00 is an unknown value RBX=0x00007f80dc8ce000 is a thread RCX=0x0000000000001a70 is an unknown value RDX=0x00007f80e14c87f0: <offset 0xe4b7f0> in /usr/java/jdk1.7.0_80/jre/lib/amd64/server/libjvm.so at 0x00007f80e067d000 RSP=0x00007f807dca4710 is pointing into the stack for thread: 0x00007f80dc8ce000 RBP=0x00007f807dca4780 is pointing into the stack for thread: 0x00007f80dc8ce000 RSI=0x00007f807dcb47f8 is pointing into the stack for thread: 0x00007f80dc8ce000 RDI=0x00007f80dc8ce1e8 is an unknown value R8 =0x00007f807dca47a0 is pointing into the stack for thread: 0x00007f80dc8ce000 R9 =0x000000000000005a is an unknown value R10=0x0000000000000000 is an unknown value R11=0x0000000000000000 is an unknown value R12=0x00007f807dcb47f8 is pointing into the stack for thread: 0x00007f80dc8ce000 R13=0x0000000000001a70 is an unknown value R14=0x0000000000000000 is an unknown value R15=0x00007f80e14c8800: <offset 0xe4b800> in /usr/java/jdk1.7.0_80/jre/lib/amd64/server/libjvm.so at 0x00007f80e067d000
此部分信息在博主的文件中存在,但在JDK 7和8兩個(gè)版本的文檔中并沒有相關(guān)說(shuō)明。但根據(jù)RAX
、RBX
等內(nèi)容推測(cè)是崩潰時(shí)CPU各個(gè)寄存器中所保存的內(nèi)容。
線程堆棧
此部分包含線程棧底及棧頂?shù)牡刂贰?dāng)前棧指針和未使用的堆??臻g。之后是堆棧幀,最多打印100幀。對(duì)于C/C++架構(gòu),可能庫(kù)名也會(huì)被打印。
當(dāng)出現(xiàn)某些致命錯(cuò)誤信息時(shí),可能堆棧已經(jīng)損壞,在這種情況下,這部分信息不可用。
Stack: [0x00007f807dbb5000,0x00007f807dcb6000], sp=0x00007f807dca4710, free space=957k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0x65395c] jni_SetByteArrayRegion+0x19c Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) J 1342 java.net.SocketInputStream.socketRead0(Ljava/io/FileDescriptor;[BIII)I (0 bytes) @ 0x00007f80d8bdc0c7 [0x00007f80d8bdc060+0x67] J 1341 C2 java.net.SocketInputStream.read([BIII)I (567 bytes) @ 0x00007f80d8bfcc90 [0x00007f80d8bfcb00+0x190] J 1258 C2 com.*.*.*.remote.internal.RemoteTCPConnection.receive([BII)I (775 bytes) @ 0x00007f80d8b87fc0 [0x00007f80d8b87f20+0xa0] J 1346 C2 com.*.*.*.remote.internal.RemoteRcvThread.receiveBuffer()I (400 bytes) @ 0x00007f80d8c05630 [0x00007f80d8c05580+0xb0] J 1032 C2 com.*.*.*.remote.internal.RemoteRcvThread.receiveOneTSH()Lcom/*/*/*/remote/internal/system/RfpTSH; (338 bytes) @ 0x00007f80d89dc354 [0x00007f80d89dc120+0x234] J 1363% C2 com.*.*.*.remote.internal.RemoteRcvThread.run()V (2498 bytes) @ 0x00007f80d8c119b8 [0x00007f80d8c11760+0x258] j java.lang.Thread.run()V+11 v ~StubRoutines::call_stub
以上日志內(nèi)容包含兩個(gè)線程堆棧:
- 第一部分堆棧是
Native frames
,打印了本地線程所有的方法調(diào)用。然而內(nèi)聯(lián)方法作為上級(jí)堆棧的一部分,線程堆棧不會(huì)考慮運(yùn)行時(shí)編譯器內(nèi)聯(lián)的Java方法。本地幀的線程堆棧信息提供關(guān)于崩潰的重要信息。通過自上而下分析列表中的庫(kù),一般可以確定引起問題的庫(kù)并報(bào)告給對(duì)應(yīng)的組織。 - 第二部分堆棧是跳過本地幀打印了內(nèi)聯(lián)方法的Java幀,根據(jù)崩潰情況可能不會(huì)打印本地幀,但大概率會(huì)打印Java幀。
其他信息
如果錯(cuò)誤發(fā)生在VM線程或編譯器線程,后邊的例子中會(huì)顯示更多信息。例如,問題出現(xiàn)在VM線程中,崩潰時(shí)VM線程正在執(zhí)行的操作將會(huì)被打印下來(lái)。下面的例子展示了編譯器線程引起崩潰,執(zhí)行的內(nèi)容是編譯器正在編譯方法hs101t004Thread.ackermann
。因?yàn)槌霈F(xiàn)的問題不一致,這部分內(nèi)容并沒有出現(xiàn)在博主的文件中。對(duì)于HotSpot虛擬機(jī)來(lái)說(shuō)這部分文件可能稍微的有點(diǎn)不同,但都會(huì)包含完整的類名和方法名。
Current CompileTask: HotSpot Client Compiler:754 b nsk.jvmti.scenarios.hotswap.HS101.hs101t004Thread.ackermann(IJ)J (42 bytes)
進(jìn)程描述
進(jìn)程相關(guān)內(nèi)容在線程之后打印,主要包含整個(gè)進(jìn)程的線程列表和內(nèi)存使用情況。
線程列表
Java Threads: ( => current thread ) 0x00007f80dc75b000 JavaThread "Thread-12" [_thread_blocked, id=93, stack(0x00007f807d8b2000,0x00007f807d9b3000)] 0x00007f80dc75a000 JavaThread "Thread-11" [_thread_blocked, id=92, stack(0x00007f807d9b3000,0x00007f807dab4000)] 0x00007f80dc759800 JavaThread "Thread-10" [_thread_blocked, id=91, stack(0x00007f807dab4000,0x00007f807dbb5000)] =>0x00007f80dc8ce000 JavaThread "RcvThread: com.*.*.*.remote.internal.RemoteTCPConnection[qmid=*,fap=10,peer=/*,localport=*,ssl=no]" daemon [_thread_in_native_trans, id=90, stack(0x00007f807dbb5000,0x00007f807dcb6000)] 0x00007f80dc636800 JavaThread "WebSphere MQ Trace Monitor" daemon [_thread_blocked, id=89, stack(0x00007f807dcb6000,0x00007f807ddb7000)] ...... Other Threads: 0x00007f80dc093800 VMThread [stack: 0x00007f807f5f6000,0x00007f807f6f7000] [id=73] 0x00007f80dc0d5000 WatcherThread [stack: 0x00007f807eeef000,0x00007f807eff0000] [id=80]
以上內(nèi)容為博主手中日志文件的內(nèi)容,因?yàn)槠鶈栴}部分內(nèi)容被省略。此部分線程列表中主要是VM已知的線程,包括Java線程和VM內(nèi)部的線程。Other Threads
部分主要包含用戶程序創(chuàng)建但沒有包含在VM內(nèi)部的本地線程。
關(guān)于線程的描述與本文之前介紹的線程部分一致。
虛擬機(jī)狀態(tài)
VM state:synchronizing (normal execution)
接下來(lái)的虛擬機(jī)狀態(tài)主要描述了虛擬機(jī)當(dāng)前的運(yùn)行狀態(tài),包含以下幾種:
虛擬機(jī)狀態(tài) | 描述 |
---|---|
not at a safepoint | 正常執(zhí)行 |
at safepoint | 虛擬機(jī)中所有線程均被阻塞,等待特殊的虛擬機(jī)操作完成 |
synchronizing | 一個(gè)特殊的虛擬機(jī)操作,需要等待虛擬機(jī)中所有的線程處于阻塞狀態(tài) |
互斥鎖/管程
VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event]) [0x00007f80dc006060] Safepoint_lock - owner thread: 0x00007f80dc093800 [0x00007f80dc0060e0] Threads_lock - owner thread: 0x00007f80dc093800 [0x00007f80dc0065e0] Heap_lock - owner thread: 0x00007f80dc5a7800
此部分描述了當(dāng)前線程持有的互斥鎖和管程。如上例所示,這些是虛擬機(jī)內(nèi)部的互斥鎖,不是Java對(duì)象關(guān)聯(lián)的管程。它展示了程序崩潰發(fā)生時(shí)虛擬機(jī)持有鎖的情況,包含了鎖名稱、持有者和虛擬機(jī)內(nèi)部互斥鎖的地址。通常情況下此部分只對(duì)非常熟悉HotSpot虛擬機(jī)的人有用。持有線程可以在線程列表中找到。
堆概覽
Heap PSYoungGen total 1397248K, used 1396672K [0x0000000755500000, 0x00000007aaa80000, 0x0000000800000000) eden space 1396224K, 100% used [0x0000000755500000,0x00000007aa880000,0x00000007aa880000) from space 1024K, 43% used [0x00000007aa880000,0x00000007aa8f0000,0x00000007aa980000) to space 1024K, 0% used [0x00000007aa980000,0x00000007aa980000,0x00000007aaa80000) ParOldGen total 2796544K, used 14720K [0x0000000600000000, 0x00000006aab00000, 0x0000000755500000) object space 2796544K, 0% used [0x0000000600000000,0x0000000600e60318,0x00000006aab00000) PSPermGen total 21504K, used 18411K [0x00000005fae00000, 0x00000005fc300000, 0x0000000600000000) object space 21504K, 85% used [0x00000005fae00000,0x00000005fbffada0,0x00000005fc300000)
此部分內(nèi)容主要為堆內(nèi)存概覽,輸出內(nèi)容取決于使用的垃圾回收器,以上內(nèi)容使用的是JDK 7默認(rèn)的組合(Parallel Scavenge+Parallel Old)。以上內(nèi)容中比較奇怪的一點(diǎn)是,我們的項(xiàng)目運(yùn)行了有一段時(shí)間了,結(jié)果老年代空間使用率約等于0%,此部分需要排查代碼,另外一點(diǎn)是新生代的使用率達(dá)到100%,說(shuō)明崩潰時(shí)可能是在對(duì)新生代進(jìn)行GC。
卡表和本地代碼緩存
Card table byte_map: [0x00007f80d7772000,0x00007f80d879c000] byte_map_base: 0x00007f80d479b000 Code Cache [0x00007f80d879c000, 0x00007f80d8f4c000, 0x00007f80db79c000) total_blobs=2892 nmethods=2508 adapters=338 free_code_cache=41446Kb largest_free_block=42334144
此部分內(nèi)容在官方文檔中沒有進(jìn)行介紹,通過查看其他資料得知,卡表是JVM維護(hù)的一種數(shù)據(jù)結(jié)構(gòu),用于記錄更改對(duì)象時(shí)的引用,以便提高GC效率,本地代碼緩存主要用于編譯和保存本地代碼。
此部分具體的用處存疑,希望有了解的大佬可以賜教。
編譯事件
Compilation events (10 events): Event: 83314.233 Thread 0x00007f80dc0c8000 nmethod 2661 0x00007f80d8f2f590 code [0x00007f80d8f2f800, 0x00007f80d8f2fd98] Event: 83314.235 Thread 0x00007f80dc0c8000 2662 ! bsh.Parser::AndExpression (232 bytes) Event: 83314.235 Thread 0x00007f80dc0c5000 nmethod 2660 0x00007f80d8f363d0 code [0x00007f80d8f366e0, 0x00007f80d8f36f68] Event: 83314.246 Thread 0x00007f80dc0c8000 nmethod 2662 0x00007f80d8f2eb50 code [0x00007f80d8f2ed40, 0x00007f80d8f2f0a0] Event: 83499.918 Thread 0x00007f80dc0c5000 2663 java.math.BigDecimal$StringBuilderHelper::putIntCompact (197 bytes) Event: 83499.930 Thread 0x00007f80dc0c5000 nmethod 2663 0x00007f80d8f2c750 code [0x00007f80d8f2c8c0, 0x00007f80d8f2cf98] Event: 84638.783 Thread 0x00007f80dc0c8000 2664 java.util.AbstractList::hashCode (46 bytes) Event: 84638.841 Thread 0x00007f80dc0c8000 nmethod 2664 0x00007f80d8f39f90 code [0x00007f80d8f3a100, 0x00007f80d8f3a378] Event: 85085.178 Thread 0x00007f80dc0c5000 2665 sun.nio.ch.EPollSelectorImpl::updateSelectedKeys (150 bytes) Event: 85085.233 Thread 0x00007f80dc0c5000 nmethod 2665 0x00007f80d8f38590 code [0x00007f80d8f387c0, 0x00007f80d8f39248]
此部分內(nèi)容在官方文檔中未進(jìn)行介紹,不過根據(jù)內(nèi)容來(lái)看,此部分包含了程序崩潰前執(zhí)行的十次編譯任務(wù)。
GC事件
GC Heap History (10 events): Event: 84610.584 GC heap before {Heap before GC invocations=309 (full 0): PSYoungGen total 1397248K, used 1396764K [0x0000000755500000, 0x00000007aaa80000, 0x0000000800000000) eden space 1396224K, 100% used [0x0000000755500000,0x00000007aa880000,0x00000007aa880000) from space 1024K, 52% used [0x00000007aa980000,0x00000007aaa071b8,0x00000007aaa80000) to space 1024K, 0% used [0x00000007aa880000,0x00000007aa880000,0x00000007aa980000) ParOldGen total 2796544K, used 14686K [0x0000000600000000, 0x00000006aab00000, 0x0000000755500000) object space 2796544K, 0% used [0x0000000600000000,0x0000000600e57bd8,0x00000006aab00000) PSPermGen total 21504K, used 18408K [0x00000005fae00000, 0x00000005fc300000, 0x0000000600000000) object space 21504K, 85% used [0x00000005fae00000,0x00000005fbffa340,0x00000005fc300000) Event: 84610.588 GC heap after Heap after GC invocations=309 (full 0): PSYoungGen total 1397248K, used 320K [0x0000000755500000, 0x00000007aaa80000, 0x0000000800000000) eden space 1396224K, 0% used [0x0000000755500000,0x0000000755500000,0x00000007aa880000) from space 1024K, 31% used [0x00000007aa880000,0x00000007aa8d0000,0x00000007aa980000) to space 1024K, 0% used [0x00000007aa980000,0x00000007aa980000,0x00000007aaa80000) ParOldGen total 2796544K, used 14686K [0x0000000600000000, 0x00000006aab00000, 0x0000000755500000) object space 2796544K, 0% used [0x0000000600000000,0x0000000600e57bd8,0x00000006aab00000) PSPermGen total 21504K, used 18408K [0x00000005fae00000, 0x00000005fc300000, 0x0000000600000000) object space 21504K, 85% used [0x00000005fae00000,0x00000005fbffa340,0x00000005fc300000) } ......
此部分內(nèi)容同樣在官方文檔中沒有說(shuō)明,但是了解JVM垃圾回收的應(yīng)該都可以看懂,因?yàn)槠鶈栴}只展示前兩段。以下對(duì)內(nèi)容進(jìn)行簡(jiǎn)要說(shuō)明:
Event: 84610.584 GC heap before | +------垃圾回收發(fā)生的時(shí)間,單位秒,從JVM啟動(dòng)開始計(jì)時(shí)
Heap before GC invocations=309 (full 0): | | | +------此前Full GC發(fā)生的次數(shù) +---------------當(dāng)前GC次數(shù)(此處代表第309次GC)
其他部分表示JVM內(nèi)存各個(gè)分區(qū)在GC前后的使用情況,如果出現(xiàn)GC后相較于GC前內(nèi)存使用量未下降的情況,則表示可能出現(xiàn)內(nèi)存溢出。
逆向優(yōu)化事件
Deoptimization events (10 events): Event: 62518.966 Thread 0x00007f80dc5a7800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8f1cea4 method=bsh.NameSpace.getClass(Ljava/lang/String;)Ljava/lang/Class; @ 16 Event: 65561.299 Thread 0x00007f801400c000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8d46158 method=sun.nio.ch.Util$BufferCache.get(I)Ljava/nio/ByteBuffer; @ 26 Event: 67079.495 Thread 0x00007f801400c000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8cad61c method=sun.nio.ch.Util$BufferCache.get(I)Ljava/nio/ByteBuffer; @ 26 Event: 67175.303 Thread 0x00007f80dc8ce000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8e80c44 method=com.*.*.*.remote.internal.system.RemoteProxyQueue.addMessage(Lcom/*/*/*/remote/internal/system/RemoteTls;Lcom/*/*/*/remote/internal/system/RfpTSH;Lcom/*/ Event: 67175.364 Thread 0x00007f801400c000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8c7c650 method=sun.nio.ch.Util$BufferCache.get(I)Ljava/nio/ByteBuffer; @ 26 Event: 70454.736 Thread 0x00007f80dc5b7000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8b23004 method=java.lang.Long.getChars(JI[C)V @ 24 Event: 70650.379 Thread 0x00007f80dc5ad000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8e0f700 method=java.util.ArrayDeque.pollFirst()Ljava/lang/Object; @ 13 Event: 76653.752 Thread 0x00007f80dc09a000 Uncommon trap: reason=bimorphic action=maybe_recompile pc=0x00007f80d8d837b4 method=java.lang.System$2.invokeFinalize(Ljava/lang/Object;)V @ 1 Event: 84618.642 Thread 0x00007f801400c000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8eef598 method=sun.nio.ch.SocketChannelImpl.translateReadyOps(IILsun/nio/ch/SelectionKeyImpl;)Z @ 140 Event: 84618.654 Thread 0x00007f801400c000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f80d8b00478 method=sun.nio.ch.EPollSelectorImpl.updateSelectedKeys()I @ 124
JVM會(huì)在運(yùn)行過程中對(duì)代碼進(jìn)行編譯優(yōu)化,過程中包含一部分不穩(wěn)定的激進(jìn)優(yōu)化,當(dāng)激進(jìn)優(yōu)化不成立時(shí)會(huì)通過逆向優(yōu)化退回到解釋狀態(tài)進(jìn)行執(zhí)行,此部分就是介紹的崩潰前的十次逆向優(yōu)化內(nèi)容,這部分內(nèi)容在官方文檔中并沒有詳細(xì)說(shuō)明。
內(nèi)部錯(cuò)誤
Internal exceptions (10 events): Event: 85322.248 Thread 0x00007f80dc5ad000 Threw 0x00000007a5d71078 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.249 Thread 0x00007f80dc5ad000 Threw 0x00000007a5d986f8 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.249 Thread 0x00007f80dc5ad000 Threw 0x00000007a5d98a20 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.249 Thread 0x00007f80dc5ad000 Threw 0x00000007a5d9b088 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.738 Thread 0x00007f80dc5a8800 Threw 0x00000007a92c18f8 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.738 Thread 0x00007f80dc5a8800 Threw 0x00000007a92c1c20 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.738 Thread 0x00007f80dc5a8800 Threw 0x00000007a92c4288 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.741 Thread 0x00007f80dc5b7000 Threw 0x00000007a982b580 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.741 Thread 0x00007f80dc5b7000 Threw 0x00000007a982b8a8 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319 Event: 85322.742 Thread 0x00007f80dc5b7000 Threw 0x00000007a982df10 at /HUDSON/workspace/7u-2-build-linux-amd64/jdk7u80/2329/hotspot/src/share/vm/prims/jvm.cpp:1319
此部分在官方文檔中并沒有進(jìn)行說(shuō)明,且當(dāng)前文件中的內(nèi)容可閱讀的信息較少,在查閱相關(guān)資料過程中發(fā)現(xiàn)部分錯(cuò)誤此處可能打印具體的異常信息。當(dāng)前文件中可以看出在0.5s內(nèi)發(fā)生了10次內(nèi)部錯(cuò)誤,綜合文件其他地方的時(shí)間來(lái)看,這個(gè)時(shí)間點(diǎn)很接近崩潰發(fā)生的時(shí)間,且與最后一次未發(fā)生的GC時(shí)間基本相符。
事件
Events (10 events): Event: 85322.248 loading class 0x00007f80dc52a460 done Event: 85322.248 loading class 0x00007f80dc52a460 Event: 85322.248 loading class 0x00007f80dc52a460 done Event: 85322.249 loading class 0x00007f80dc52a460 Event: 85322.249 loading class 0x00007f80dc52a460 done Event: 85322.738 loading class 0x00007f80dc52a460 Event: 85322.738 loading class 0x00007f80dc52a460 done Event: 85322.741 loading class 0x00007f80dc52a460 Event: 85322.741 loading class 0x00007f80dc52a460 done Event: 85322.742 Executing VM operation: ParallelGCFailedAllocation
此部分在官方文檔中并沒有進(jìn)行說(shuō)明,此部分主要包含JVM在崩潰前的十次操作事件,以上內(nèi)容可以看出最后一次事件為ParallelGCFailedAllocation,在網(wǎng)上沒有查到這個(gè)操作的資料,根據(jù)字面含義為執(zhí)行Parallel垃圾回收器回收失敗后的再分配過程,此處的疑點(diǎn)是在崩潰前新生代內(nèi)存使用率已經(jīng)是100%了,可能是這個(gè)事件導(dǎo)致的內(nèi)存溢出。
內(nèi)存信息
Dynamic libraries: 00400000-00401000 r-xp 00000000 fd:01 268667146 /usr/java/jdk1.7.0_80/bin/java 00600000-00601000 rw-p 00000000 fd:01 268667146 /usr/java/jdk1.7.0_80/bin/java 01097000-010b8000 rw-p 00000000 00:00 0 [heap] ...... 7f80e210c000-7f80e210d000 r--p 0001f000 fd:01 302335055 /usr/lib64/ld-2.17.so 7f80e210d000-7f80e210e000 rw-p 00020000 fd:01 302335055 /usr/lib64/ld-2.17.so 7f80e210e000-7f80e210f000 rw-p 00000000 00:00 0 7fff254c6000-7fff254e7000 rw-p 00000000 00:00 0 [stack] 7fff25514000-7fff25516000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
此部分信息展示了崩潰時(shí)的內(nèi)存信息,這個(gè)列表在比較大的應(yīng)用程序中可能會(huì)比較長(zhǎng),博主的文件中這一部分不算空行占了350多行。此部分在調(diào)試崩潰情況時(shí)非常有用,可以描述被使用的庫(kù)及其使用的內(nèi)存地址,以及堆、棧和保護(hù)單元的地址。
此部分內(nèi)容的格式與操作系統(tǒng)相關(guān),以上例子為L(zhǎng)inux下的格式,以下是對(duì)內(nèi)容的簡(jiǎn)單介紹:
?日志內(nèi)容 | 實(shí)際含義 |
---|---|
00400000-00401000 | 內(nèi)存區(qū)域 |
r-xp | 權(quán)限(r:讀取、w:寫入、x:執(zhí)行、p:私有、s:共享) |
00000000 | 文件偏移量 |
fd:01 | 文件所在設(shè)備的主要和次要ID |
268667146 | 索引編號(hào) |
/usr/java/jdk1.7.0_80/bin/java | 文件名 |
00400000-00401000 r-xp 00000000 fd:01 268667146 /usr/java/jdk1.7.0_80/bin/java |<------------->| ^ ^ ^ ^ |<- -------------------------->| | | | | | | | | | | | +------------------- 文件名 | | | | +------------------------------------------- 索引編號(hào) | | | +------------------------------------------------- 文件所在設(shè)備的主要和次要ID | | +--------------------------------------------------------- 文件偏移量 | +---------------------------------------------------------------- 權(quán)限(r:讀取、w:寫入、x:執(zhí)行、p:私有、s:共享) +--------------------------------------------------------------------------- 內(nèi)存區(qū)域
虛擬機(jī)參數(shù)和環(huán)境變量
VM Arguments: jvm_args: -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 -Xms4096m -Xmx8192m java_command: com.giantstone.commgateway.startup.Bootstrap ../../gateway-comm-lib/lib ../config ../deploy front_core start Launcher Type: SUN_STANDARD Environment Variables: PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin SHELL=/bin/bash
此部分應(yīng)該是最簡(jiǎn)單易懂的,描述的是和Java虛擬機(jī)有關(guān)的環(huán)境變量及其自身運(yùn)行時(shí)使用的參數(shù)。
信號(hào)處理器
Signal Handlers: SIGSEGV: [libjvm.so+0x9a3b20], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004 SIGBUS: [libjvm.so+0x9a3b20], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004 SIGFPE: [libjvm.so+0x81e740], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004 SIGXFSZ: [libjvm.so+0x81e740], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004 SIGILL: [libjvm.so+0x81e740], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004 SIGUSR1: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000000 SIGUSR2: [libjvm.so+0x81ffb0], sa_mask[0]=0x00000000, sa_flags=0x10000004 SIGHUP: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000 SIGINT: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000 SIGTERM: [libjvm.so+0x8210d0], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004 SIGQUIT: [libjvm.so+0x8210d0], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004
此部分內(nèi)容為L(zhǎng)inux特有的內(nèi)容,主要描述針對(duì)信號(hào)所使用的處理程序。
系統(tǒng)信息
日志最后一大部分是操作系統(tǒng)相關(guān)的內(nèi)容,也是整個(gè)文件當(dāng)中最直觀的部分,主要包含操作系統(tǒng)版本、CPU信息和內(nèi)存概要。
操作系統(tǒng)
OS:Red Hat Enterprise Linux Server release 7.0 (Maipo) uname:Linux 3.10.0-514.el7.x86_64 #1 SMP Wed Oct 19 11:24:13 EDT 2016 x86_64 libc:glibc 2.17 NPTL 2.17 rlimit: STACK 8192k, CORE infinity, NPROC infinity, NOFILE 65536, AS infinity load average:6.02 5.99 5.89
此部分內(nèi)容為針對(duì)操作系統(tǒng)的基本信息和運(yùn)行中的平均負(fù)載情況。
內(nèi)存信息
Memory: 4k page, physical 131862044k(14543760k free), swap 33554428k(33531212k free) /proc/meminfo: MemTotal: 131862044 kB MemFree: 14543760 kB MemAvailable: 120724836 kB Buffers: 1584 kB Cached: 107254088 kB ...... HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 378736 kB DirectMap2M: 133838848 kB
內(nèi)存部分在文件中實(shí)際分了兩部分,這里我們放在一起展示,因?yàn)槠騼?nèi)存詳情只展示開頭和結(jié)尾的部分,這部分主要包含系統(tǒng)運(yùn)行時(shí)的內(nèi)存使用情況,這里有個(gè)問題,我們的應(yīng)用跑在容器之中,分配的容器內(nèi)存只有8G,但這里獲取到的內(nèi)存則是整臺(tái)宿主機(jī)的內(nèi)存。
CPU信息
CPU:total 32 (1 cores per cpu, 1 threads per core) family 6 model 6 stepping 3, cmov, cx8, fxsr, mmx, sse, sse2, sse3, tsc /proc/cpuinfo: # 此處省略掉每個(gè)CPU核心的描述信息
MAKEFILE 復(fù)制 全屏
CPU信息部分包括概覽以及對(duì)每個(gè)核心的描述,因?yàn)槠蚴÷缘袅耍颂幒蛢?nèi)存存在同樣的問題,容器內(nèi)的應(yīng)用獲取到了宿主機(jī)的CPU信息。
總結(jié)
通過查詢相關(guān)資料,對(duì)JVM致命錯(cuò)誤日志內(nèi)容有了初步的了解,在學(xué)習(xí)的過程中發(fā)現(xiàn)了以下幾個(gè)疑點(diǎn):
- 崩潰時(shí)正在通過JNI方式調(diào)用SetByteArrayRegion這個(gè)方法進(jìn)行數(shù)組處理,通過堆棧信息可以看到是在調(diào)用RemoteTCPConnection.receive()時(shí)報(bào)的錯(cuò),而這個(gè)類是我們引用的MQ中的方法,后續(xù)需要對(duì)相關(guān)的代碼進(jìn)行排查,確定使用的版本是否正常,相關(guān)代碼是否存在問題。
- 在查看堆內(nèi)存和事件部分可以得知,在崩潰時(shí)內(nèi)存中新生代的使用率已經(jīng)達(dá)到了100%,在事件中也觸發(fā)了ParallelGCFailedAllocation,考慮是不是因?yàn)樵谡{(diào)用RemoteTCPConnection.receive()時(shí)出現(xiàn)了內(nèi)存溢出問題。
- 容器內(nèi)的應(yīng)用在獲取硬件信息時(shí)獲取到了宿主機(jī)的硬件信息,這個(gè)地方會(huì)有一個(gè)隱患,java默認(rèn)使用物理內(nèi)存的一半來(lái)作為虛擬機(jī)的內(nèi)存,如果說(shuō)在使用java時(shí)沒有手動(dòng)設(shè)定
Xmx
參數(shù),也就意味著該進(jìn)程使用的內(nèi)存可能會(huì)遠(yuǎn)大于容器的內(nèi)存。此份日志文件中可以看到設(shè)置的-Xmx=8192m
,但實(shí)際我們給容器分配的內(nèi)存也是8G,而另外的應(yīng)用中使用的Tomcat并沒有設(shè)置此參數(shù)。 - 在排查問題時(shí)還發(fā)現(xiàn)JDK 7本身與容器存在兼容性問題,網(wǎng)上的資料建議使用JDK 8u131以后的版本,但是博主未在JDK 8u131的更新日志中發(fā)現(xiàn)相關(guān)內(nèi)容,倒是在8u191的更新日志中找到了,目前計(jì)劃將JDK更新至8u201,同時(shí)使用G1垃圾回收器,驗(yàn)證能不能解決之前出現(xiàn)的GC問題。
以上是排查過程中發(fā)現(xiàn)的問題,本人水平有限,可能問題定位不準(zhǔn)確,這份總結(jié)僅供各位參考,實(shí)際的問題還需要多方面的排查和驗(yàn)證。
到此這篇關(guān)于JVM致命錯(cuò)誤日志詳解的文章就介紹到這了,更多相關(guān)JVM致命錯(cuò)誤日志詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Boot?整合?Fisco?Bcos部署、調(diào)用區(qū)塊鏈合約的案例
本篇文章介紹?Spring?Boot?整合?Fisco?Bcos?的相關(guān)技術(shù),最最重要的技術(shù)點(diǎn),部署、調(diào)用區(qū)塊鏈合約的工程案例,本文通過流程分析給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-01-01詳解Springboot應(yīng)用中設(shè)置Cookie的SameSite屬性
Chrome 51 開始,瀏覽器的 Cookie 新增加了一個(gè)SameSite屬性,用來(lái)防止 CSRF 攻擊和用戶追蹤。今天通過本文給大家介紹Springboot應(yīng)用中設(shè)置Cookie的SameSite屬性,感興趣的朋友一起看看吧2022-01-01springboot結(jié)合JWT實(shí)現(xiàn)單點(diǎn)登錄的示例
本文主要介紹了springboot結(jié)合JWT實(shí)現(xiàn)單點(diǎn)登錄的示例,包括生成Token、驗(yàn)證Token及使用Redis存儲(chǔ)Token,具有一定的參考價(jià)值,感興趣的可以了解一下2025-01-01Spring Security登錄接口兼容JSON格式登錄實(shí)現(xiàn)示例
前后端分離中,前端和后端的數(shù)據(jù)交互通常是JSON格式,本文主要介紹了Spring Security登錄接口兼容JSON格式登錄實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01解決@RequestBody接收json對(duì)象報(bào)錯(cuò)415的問題
這篇文章主要介紹了解決@RequestBody接收json對(duì)象報(bào)錯(cuò)415的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06