深入理解JVM虛擬機——JVM內存分析命令

JVM內存分析命令
工欲善其事,必先利其器!
JVM本身和開源界提供了很多豐富的方法和工具來幫助開發者查看和分析JVM內存狀況。通過這些分析,可以排查程序中內存問題及調優程序的性能。下面介紹幾個常用的命令工具。
測試環境:

java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
一、jps:虛擬機進程狀況工具(常用)
java process status(jps) 用於查看正在運行的java程序的狀態
# 用法
$ jps [ options ] [ hostid ]

jps -m  (常用)顯示主函數輸入的參數
jps -l  (常用)顯示應用程序主類完整/全限定包類名或jar完整名稱
jps -v  (常用)列出程序啓動時的jvm參數
jps -V   輸出通過.hotsportrc或-XX:Flags=<filename>指定的jvm參數
二、jstat:虛擬機統計信息監視工具
jstat是jvm statistics 的縮寫
用法
$ jstat [ option lvmid [ interval[s|ms] [count] ] ]
類加載統計:
$ jstat -class 7658
Loaded  Bytes  Unloaded  Bytes     Time   
 10381 19456.3       80   117.8       6.71
Loaded:已加載的class數量
Bytes:已加載所佔用空間大小
Unloaded:未加載的class數量
Bytes:未加載所佔用空間大小
Time:加載所用時間
常用的統計命令:
$ jstat -gcutil 7658 5s 2
 S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
62.50   0.00  67.59  46.13  98.26  97.07  10662   36.514     3    0.286   36.800
62.50   0.00  73.00  46.13  98.26  97.07  10662   36.514     3    0.286   36.800
S0、S1:分別表示新生代的兩個Survivor區
E :Eden區使用佔比
O:老年代使用佔比
M:元數據空間使用佔比
CCS:壓縮使用佔比
YGC:年輕代垃圾回收次數
FGC:老年代垃圾回收次數
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間
二、jinfo:Java配置信息查看工具
這個命令工具不常用,舉個查看年輕代大小的命令:
$ jinfo -flag NewSize 7658
-XX:NewSize=44564480
三、jmap:Java內存影像工具(非常重要)
用法:
$ jmap [option] <pid>
    (to connect to running process)
$ jmap [option] <executable <core>
    (to connect to a core file)
$ jmap [option] [server_id@]<remote server IP or hostname>
    (to connect to remote debug server)
舉例與說明:
$ jmap -heap 7658
Attaching to process ID 7658, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.171-b11

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:         # Heap堆配置信息
   MinHeapFreeRatio         = 0 # JVM堆最小空閒比率(default 40)
   MaxHeapFreeRatio         = 100  # JVM堆最大空閒比率(default 70)
   MaxHeapSize              = 536870912 (512.0MB) # 堆最大值,可以通過 -XX:MaxHeapSize 或 -Xmx設置
   NewSize                  = 44564480 (42.5MB) # 新生代大小
   MaxNewSize               = 178782208 (170.5MB) # 新生代的最大大小
   OldSize                  = 89653248 (85.5MB) # 老年代大小
   NewRatio                 = 2 # 新生代與老生代的大小比率 1:2
   SurvivorRatio            = 8 # 年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:8,表示Eden:Survivor=8:2
   MetaspaceSize            = 21807104 (20.796875MB) # jdk1.7有永久代,jdk1.8更換成了Metaspace
   CompressedClassSpaceSize = 1073741824 (1024.0MB)  # class信息存放的空間大小
   MaxMetaspaceSize         = 17592186044415 MB # Metaspace是使用的直接內存,理論上可以無限大(內存+硬盤緩衝區)
   G1HeapRegionSize         = 0 (0.0MB) # 設置的 G1 區域的大小。值是 2 的冪,範圍是 1 MB 到 32 MB 之間。目標是根據最小的 Java 堆大小劃分出約 1024/2048 個區域。

Heap Usage: # 堆內存的使用情況
PS Young Generation # 新生代
Eden Space: # Eden空間
   capacity = 50331648 (48.0MB) # 容量
   used     = 37253928 (35.528114318847656MB) # 已使用容量
   free     = 13077720 (12.471885681152344MB) # 空閒容量
   74.01690483093262% used # 使用率
From Space: # From Survivor 空間
   capacity = 524288 (0.5MB) # 容量
   used     = 327680 (0.3125MB) # 已使用容量
   free     = 196608 (0.1875MB) # 空閒容量
   62.5% used # 使用率
To Space: # To Survivor 空間
   capacity = 524288 (0.5MB) # 容量
   used     = 0 (0.0MB) # 已使用容量
   free     = 524288 (0.5MB) # 空閒容量
   0.0% used # 使用率
PS Old Generation # 老年代
   capacity = 125304832 (119.5MB) # 容量
   used     = 57833832 (55.154640197753906MB) # 已使用容量
   free     = 67471000 (64.3453598022461MB) # 空閒容量
   46.15451062573548% used # 使用率

28116 interned Strings occupying 3331608 bytes.
當然也可以生成內存映射快照:
$ jmap -dump:live,format=b,file=jmap-7658.hprof 7658
Dumping heap to /opt/applications/xxx/data/jmap-7658.hprof ...
Heap dump file created
然後可使用 jvisualvm 等工具進行分析,它在Java\jdk1.8.0_141\bin\jvisualvm.exe。該工具適用於jdk7/8/9,如果你使用jdk11,就用不了這個jvisualvm** 工具了,你可以使用其他工具或下面的 jhat 命令分析。

四、jhat 堆分析工具
全稱Java Heap Analyse Tool,Java堆分析工具。是對堆內存轉儲快照文件分析的一種命令工具,它會啓動一個Web Server,然後通過瀏覽器就可以分析轉儲快照了。
如果你在使用 jdk11,也沒安裝其他版本的jdk,進而不能使用 jvisualvm 這個工具,現在你可以使用 jhat 來分析堆轉儲快照了。
$ jhat -J-Xmx1024m jmap-7658.hprof
Reading from jmap-7658.hprof...
Dump file created Tue Nov 13 15:37:02 CST 2018
Snapshot read, resolving...
Resolving 655822 objects...
Chasing references, expect 131 dots...................................................................................................................................
Eliminating duplicate references...................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
上面 -Xmx1024m 參數可以控制啓動應用的堆內存大小。

然後通過瀏覽器訪問界面:http://111.111.108.78:7000/

五、jstack 堆棧跟蹤工具(非常重要)
前面的文章已經講解過,棧是線程私有區域,也是邏輯處理的重要區域。如果邏輯計算出了問題,分析棧內存區域時非常重要的。
jstack 是java虛擬機自帶的一種堆棧跟蹤工具。
用法
$ jstack [-l] <pid>
    (to connect to running process)
$ jstack -F [-m] [-l] <pid>
    (to connect to a hung process)
$ jstack [-m] [-l] <executable> <core>
    (to connect to a core file)
$ jstack [-m] [-l] [server_id@]<remote server IP or hostname>
    (to connect to a remote debug server)

# -F:強制dump線程信息 
# -m:dump虛擬機棧和本地方法棧 
# -l:長期監聽,dump鎖信息
$ jstack -l 7658 > thread-7658.txt
信息都dump到這個 thread-7658.txt 文件中。
六、友情繫統命令:top
一般LInux 操作系統版服務器是不安裝可視化界面的,不能像Windows那樣通過任務管理器來查看 進程 和 性能。
top 命令是Linux下常用的 性能分析工具,能夠實時顯示系統中各個進程的資源佔用狀況,類似於Windows的任務管理器。
前操作系統版本: CentOS Linux release 7.3.1611 (Core)
不同的操作系統、不同的版本命令略有差異。
$ top -hv | -bcHiOSs -d secs -n max -u|U user -p pid(s) -o field -w [cols]
# -d -n -p 都是非常常用的參數,分佈表示 刷新時間間隔(單位秒)、刷新次數、指定的進程id
top 無參命令
$ top
top - 17:32:26 up 207 days,  3:38,  2 users,  load average: 0.02, 0.05, 0.05
Tasks: 133 total,   1 running, 132 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.3 sy,  0.0 ni, 99.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16267428 total,   225800 free, 15516244 used,   525384 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   414824 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                   
 9504 root      20   0 7779792 1.458g    516 S   4.0  9.4   1851:46 java                                                      
 2395 root      20   0 9382196 1.793g   6260 S   2.7 11.6   1246:57 java                                                      
 6339 root      20   0 7700880 1.415g    468 S   2.0  9.1   2243:56 java                                                      
12748 root      20   0 8916252 1.155g   3988 S   1.3  7.4   1776:47 java                                                      
 7003 root      20   0 2522348  75868   2852 S   1.0  0.5   1211:32 java               ...
最上面展示了日期、任務、CPU、內存、交換區等使用情況。
PID:進程id
USER:當前用戶
PR:進程優先級
NI:nice值,負值表示優先級高,正值表示優先級低
VIRT:進程使用的虛擬內存,單位kb。VIRT=SWAP+RES
RES: 進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA
SHR:共享內存大小,單位kb
S:進程狀態。D:不可中斷的睡眠狀態;R:運行; S:睡眠 ;T:跟蹤/停止;Z:殭屍進程
%CPU:CPU使用百分比(注:一個CPU最大百分比是100%,兩個CPU最大百分比是200%,以此類推)
%MEM:內存使用百分比
TIME+:進程累計使用CPU的時間,單位1/100s
COMMAND:進程名稱
top -d -n -p 有參
$ top -d 5 -n 20 -p 2395 # 表示每5秒分析一次,共動態分析20詞,監視的進程號2395
top - 09:30:02 up 207 days, 19:35,  2 users,  load average: 0.00, 0.02, 0.05
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.0 us,  0.3 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16267428 total,   175448 free, 15553816 used,   538164 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   382452 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                   
 2395 root      20   0 9382196 1.807g   6252 S   7.4 11.6   1270:55 java

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章