這個問題阿里經常問,參考:阿里面試
結論:
(1)棧信息:jstack <pid>輸出的信息。
(2)堆信息:jmap -dump <pid>輸出的文件,
(3)jstat查看gc情況,jstat -gc <PID> 間隔毫秒數 比如 jstat -gc 12345 5000 也就是每隔5秒打印進程12345的 gc情況
一、看一下 jstack
jstack -m <pid> >jvm_deadlocks.txt jstack -l <pid> >jvm_listlocks.txt 參考資料 jstack - Stack Trace
使用top -H -p <pid>找出某進程中要分析的線程ID,然后將線程ID轉換為16進制后,在線程dump文件中搜索相關信息
首先看一下我自己在項目中使用 jstack如何查詢問題:
可以使用jstat查看 gc情況 jstat -gc 12345 5000 (jstat -gc 進程號 間隔毫秒數)
定位問題
(1) 首先 找到相應的進程 使用 ps -ef | grep 'com.sankuai.qcs.regulation.dispatch'
找到進程的ID;==>21980
(2) top -Hp 21980(查詢耗時最高的線程),發現有個線程確實不正常;
(3)jstack 21980 |grep '線程的16進制的ID'
注意 在第二步查到線程的ID之后,轉換成16進制的。放在(3)里面;
同事查的:
進入系統 使用 grep -n 'java.lang.Thread.State:BLOCKED' jstack.log -A5;
查詢:
Java通過jvm自己管理內存,同時Java提供了一些命令行工具,用於查看內存使用情況。
這里主要介紹一下jstat、jmap命令以及相關工具。
很多情況下,都會出現dump這個字眼,java虛擬機jvm中也不例外,其中主要包括內存dump、線程dump。
當發現應用內存溢出或長時間使用內存很高的情況下,通過內存dump進行分析可找到原因。
當發現cpu使用率很高時,通過線程dump定位具體哪個線程在做哪個工作占用了過多的資源。
首先,內存dump是指通過jmap -dump <pid>輸出的文件,而線程dump是指通過jstack <pid>輸出的信息。
兩個dump可以單獨使用,也可以在特定場合下結合使用。
在linux操作系統下(已安裝jdk),執行jps命令,列出正在運行的java程序的進程ID。
使用top查看目前正在運行的進程使用系統資源情況。
其中進程號為24660的進程,jps輸出列表和top列表中都出現,並且在top列表中顯示是由java COMMAND啟動的。
其中%MEM為2.9,說明占用系統內存為2.9%,當前系統大概8G內存;另外%CPU指的是當前進程使用CPU資源百分比;
二、看一下jmap:
jmap -heap 2083
可以觀察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的內存使用情況
jmap -dump:format=b,file=heapdump.hprof <pid>
jmap -histo 2083 | jmap -histo:live 2083
可以觀察heap中所有對象的情況(heap中所有生存的對象的情況)。包括對象數量和所占空間大小。
[C is a char[]
[S is a short[] [I is a int[] [B is a byte[] [[I is a int[][]
JVM version is 25.65-b01
using parallel threads in the new generation. using thread-local object allocation. Concurrent Mark-Sweep GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 8388608000 (8000.0MB) NewSize = 2006515712 (1913.5625MB) MaxNewSize = 2006515712 (1913.5625MB) OldSize = 90636288 (86.4375MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 1805910016 (1722.25MB) used = 788045040 (751.5383148193359MB) free = 1017864976 (970.7116851806641MB) 43.637004779755316% used Eden Space: capacity = 1605304320 (1530.9375MB) used = 630378472 (601.1757583618164MB) free = 974925848 (929.7617416381836MB) 39.26847166274367% used From Space: capacity = 200605696 (191.3125MB) used = 157666568 (150.36255645751953MB) free = 42939128 (40.94994354248047MB) 78.59525982751757% used To Space: capacity = 200605696 (191.3125MB) used = 0 (0.0MB) free = 200605696 (191.3125MB) 0.0% used concurrent mark-sweep generation: capacity = 6382092288 (6086.4375MB) used = 4612472232 (4398.79630279541MB) free = 1769620056 (1687.6411972045898MB) 72.27210174745753% used 18841 interned Strings occupying 1633048 bytes.
【內存dump】
jmap –dump:live,format=b,file=heap.bin <pid>
參考資料:jmap - Memory Map
將生成的heap.bin文件,使用ha456.jar工具打開分析。java -jar -Xmx3000m ha456.jar
三、jstat查看 gc實時執行情況
interval,間隔時間,單位為秒或者毫秒
count,打印次數,如果缺省則打印無數次

標志
|
說明
|
S0C
|
年輕代中第一個survivor區的容量 (字節)
|
S1C
|
年輕代中第二個survivor區的容量 (字節)
|
S0U
|
年輕代中第一個survivor區目前已使用空間 (字節)
|
S1U
|
年輕代中第二個survivor區目前已使用空間 (字節)
|
EC
|
年輕代中Eden的容量 (字節)
|
EU
|
年輕代中Eden目前已使用空間 (字節)
|
OC
|
Old代的容量 (字節)
|
OU
|
Old代目前已使用空間 (字節)
|
PC
|
Perm(持久代)的容量 (字節)
|
PU
|
Perm(持久代)目前已使用空間 (字節)
|
YGC
|
從應用程序啟動到采樣時年輕代中gc次數
|
YGCT
|
從應用程序啟動到采樣時年輕代中gc所用時間(s)
|
FGC
|
從應用程序啟動到采樣時old代(全gc)gc次數
|
FGCT
|
從應用程序啟動到采樣時old代(全gc)gc所用時間(s)
|
GCT
|
從應用程序啟動到采樣時gc用的總時間(s)
|
NGCMN
|
年輕代(young)中初始化(最小)的大小 (字節)
|
NGCMX
|
年輕代(young)的最大容量 (字節)
|
NGC
|
年輕代(young)中當前的容量 (字節)
|
OGCMN
|
old代中初始化(最小)的大小 (字節)
|
OGCMX
|
old代的最大容量 (字節)
|
OGC
|
old代當前新生成的容量 (字節)
|
PGCMN
|
perm代中初始化(最小)的大小 (字節)
|
PGCMX
|
perm代的最大容量 (字節)
|
PGC
|
perm代當前新生成的容量 (字節)
|
S0
|
年輕代中第一個survivor區已使用的占當前容量百分比
|
S1
|
年輕代中第二個survivor區已使用的占當前容量百分比
|
E
|
年輕代中Eden已使用的占當前容量百分比
|
O
|
old代已使用的占當前容量百分比
|
P
|
perm代已使用的占當前容量百分比
|
S0CMX
|
年輕代中第一個survivor區的最大容量 (字節)
|
S1CMX
|
年輕代中第二個survivor區的最大容量 (字節)
|
ECMX
|
年輕代中Eden的最大容量 (字節)
|
DSS
|
當前需要survivor區的容量 (字節)(Eden區已滿)
|
TT
|
持有次數限制
|
MTT
|
最大持有次數限制
|
grant codebase " file:$JAVA_HOME/lib/tools.jar " {
permission java.security.AllPermission;
};
|