Java虛擬機五:常用內存分析命令和工具


一、常用命令

1、jps

  jps(JVM Process Status),可以列出虛擬機內的進程,並顯示虛擬機執行主類名稱以及這些進程的本地虛擬機唯一ID,該ID與操作系統的進程ID一致,jps命令格式為:  jps [options] [hostid] 

  其中options為該命令的選項,hostid為虛擬機中進程的唯一ID,也是linux下系統中進程的pid,options有如下取值:

選項 說明
-q 只顯示進程id,不顯示主類
-m 輸出虛擬機進程啟動時傳遞給主類的參數
-l 列出主類的全名,如果進程執行的是Jar包,則列出Jar包的路徑
-v 輸出虛擬機進程啟動時候的參數

  命令示例如下:

[root@localhost software]# jps
74946 Jps
65684 Bootstrap
[root@localhost software]# jps -q
65684
75052
[root@localhost software]# jps -l
65684 org.apache.catalina.startup.Bootstrap
75160 sun.tools.jps.Jps
[root@localhost software]# jps -m
75298 Jps -m
65684 Bootstrap start
[root@localhost software]# jps -v
65684 Bootstrap -Djava.util.logging.config.file=/usr/local/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/usr/local/tomcat8 -Dcatalina.home=/usr/local/tomcat8 -Djava.io.tmpdir=/usr/local/tomcat8/temp
75628 Jps -Denv.class.path=/usr/local/jdk/lib/ -Dapplication.home=/usr/local/jdk -Xms8m
[root@localhost software]# 

 

 2、jstat

  jstat(JVM Statistics Monitoring Tool)命令主要用來監控虛擬機運行狀態信息,其命令格式為 jstat [options] [vmid] [interval[m|ms]] [count] 

  其中,options選項用來確定需要監視虛擬機的哪部分數據,vmid為本地虛擬機進程id,interval用於控制監控的時間間隔,可以加m|ms單位,count用來控制監控的次數。options選項取值如下:

選項 說明
-class 監控類裝載,卸載數量,總空間以及類裝載所耗費的時間
-gc 監視Java堆狀況,包括Eden區,兩個Survivor區,老年代等的容量,已用空間,GC時間合計等信息
-gccapacity 監視內容與-gc一樣,但只要關注Java堆中各個區域使用到的最大,最小空間
-gcutil 監視內容與-gc一樣,但只要關注已使用空間占總空間的百分比
-gccause 與-gcutil功能一樣,但會額外輸出導致上一次GC的原因
-gcnew 監視新生代GC狀況
-gcnewcapacity 監視內容與-gcnew一樣,但是主要關注使用新生代使用的最大,最小空間
-gcold 監視老年代GC狀況
-gcoldcapacity 監視內容與-gcold一樣,但是主要關注老年代使用的最大,最小空間
-compiler 輸出JIT編譯器編譯過的方法,耗時等信息
-printcompilation 輸出已經被JIT編譯的方法

  命令示例如下:

[root@localhost software]# jstat -gc 65684 1s 2
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
704.0  704.0   0.0    0.0    6016.0   1369.2   14820.0     6365.8   18176.0 17511.6 2048.0 1922.7     12    0.134   2      0.392    0.526
704.0  704.0   0.0    0.0    6016.0   1369.2   14820.0     6365.8   18176.0 17511.6 2048.0 1922.7     12    0.134   2      0.392    0.526
[root@localhost software]# jstat -gcold 65684 1s 2
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
 18176.0  17511.6   2048.0   1922.7     14820.0      6365.8     12     2    0.392    0.526
 18176.0  17511.6   2048.0   1922.7     14820.0      6365.8     12     2    0.392    0.526
[root@localhost software]# 

3、jmap

  jmap命令的主要作用是生成堆轉儲文件,其命令格式為: jmap [option] vmid 

  其中,option的取值有如下幾種:

選項 說明
-dump 用於生成堆轉儲快照文件,命令格式為:jmap -dump:[live,]format=b,file=<filename>,其中live參數表示只dump出存活的對象,命令示例: jmap -dump:format=b,file=./result.hprof 65684 ;或者 jmap -dump:live,format=b,file=./result.hprof 65684 
-finalizerinfo 顯示在F-QUeue中等待Finalizer線程執行finalize方法的對象,如: jmap -finalizerinfo 65684 
-heap 顯示Java堆詳細信息,如使用哪種垃圾回收期,參數配置,分代狀況等。如: jmap -heap 65684 
-histo 顯示堆中對象統計信息,包括類,實例數量,合計容量。如: jmap -histo 65684 
-F 當虛擬機對-dump命令沒有響應的時候,可以使用該參數強制生成dump文件

  常用例子:

  (1)生成dump文件:

[root@localhost software]# jmap -dump:format=b,file=./dumpresult.hprof 65684
Dumping heap to /software/dumpresult.hprof ...
Heap dump file created
[root@localhost software]# 

  (2)查看Java堆詳細信息:

[root@localhost software]# jmap -heap 65684
Attaching to process ID 65684, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.211-b12

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 257949696 (246.0MB)
   NewSize                  = 5570560 (5.3125MB)
   MaxNewSize               = 85983232 (82.0MB)
   OldSize                  = 11206656 (10.6875MB)
   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 = 6881280 (6.5625MB)
   used     = 1330704 (1.2690582275390625MB)
   free     = 5550576 (5.2934417724609375MB)
   19.338030133928573% used
Eden Space:
   capacity = 6160384 (5.875MB)
   used     = 1330704 (1.2690582275390625MB)
   free     = 4829680 (4.6059417724609375MB)
   21.60099110704787% used
From Space:
   capacity = 720896 (0.6875MB)
   used     = 0 (0.0MB)
   free     = 720896 (0.6875MB)
   0.0% used
To Space:
   capacity = 720896 (0.6875MB)
   used     = 0 (0.0MB)
   free     = 720896 (0.6875MB)
   0.0% used
tenured generation:
   capacity = 15175680 (14.47265625MB)
   used     = 6518560 (6.216583251953125MB)
   free     = 8657120 (8.256072998046875MB)
   42.953989541160595% used

13442 interned Strings occupying 1162192 bytes.
[root@localhost software]# 

4、jstack

  jstack用於生成虛擬機當前時刻的線程快照(threaddump文件),命令格式為 jstack [option] vmid 。

  其中option具體取值如下:

參數 說明
-F 當正常輸出的請求不被響應時,強制輸出線程堆棧
-l 除堆棧外,顯示關於鎖的信息
-m 如果調用到本地方法的話,可以顯示C/C++的堆棧

 

  使用 jstack -l 65684>./result.txt 命令,將線程堆棧保存到result.txt中進行分析

5.jcmd

  jcmd命令格式為 jcmd [vmid] [option] ,具體的option取值,可以使用 jcmd [vmid] help 命令查看:

[root@localhost software]# jcmd 65684 help
65684:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help

For more information about a specific command use 'help <command>'.
[root@localhost software]#

使用示例:使用jcmd打印NativeMemoryTracking,分析堆外內存

  首先需要配置JVM參數 -XX:NativeMemoryTracking=[off | summary | detail] 。在tomcat的 catalina.sh 中加入 JAVA_OPTS="-XX:NativeMemoryTracking=detail" ,然后使用命令 jcmd 112352 VM.native_memory summary 查看內存:

[root@localhost bin]# jcmd 112352 VM.native_memory summary
112352:

Native Memory Tracking:

Total: reserved=1614878KB, committed=85806KB
-                 Java Heap (reserved=251904KB, committed=16384KB)
                            (mmap: reserved=251904KB, committed=16384KB) 
 
-                     Class (reserved=1063348KB, committed=15412KB)
                            (classes #2372)
                            (malloc=436KB #2468) 
                            (mmap: reserved=1062912KB, committed=14976KB) 
 
-                    Thread (reserved=42331KB, committed=42331KB)
                            (thread #42)
                            (stack: reserved=42148KB, committed=42148KB)
                            (malloc=135KB #207) 
                            (arena=48KB #80)
 
-                      Code (reserved=250457KB, committed=5605KB)
                            (malloc=857KB #1584) 
                            (mmap: reserved=249600KB, committed=4748KB) 
 
-                        GC (reserved=836KB, committed=72KB)
                            (malloc=8KB #109) 
                            (mmap: reserved=828KB, committed=64KB) 
 
-                  Compiler (reserved=141KB, committed=141KB)
                            (malloc=10KB #89) 
                            (arena=131KB #5)
 
-                  Internal (reserved=783KB, committed=783KB)
                            (malloc=751KB #3761) 
                            (mmap: reserved=32KB, committed=32KB) 
 
-                    Symbol (reserved=4358KB, committed=4358KB)
                            (malloc=2848KB #17221) 
                            (arena=1511KB #1)
 
-    Native Memory Tracking (reserved=544KB, committed=544KB)
                            (malloc=118KB #1670) 
                            (tracking overhead=426KB)
 
-               Arena Chunk (reserved=176KB, committed=176KB)
                            (malloc=176KB) 
 
[root@localhost bin]# 

二、常用工具

  MAT(Eclipse Memory Analyzer )是一個Eclipse插件,可以在Eclipse中安裝,也可以獨立運行。使用MAT進行內存分析非常方便。其下載地址為:https://www.eclipse.org/mat/downloads.php

  選擇合適的版本下載,解壓后即可使用。

  要分析內存,首先要獲取dump文件,可以通過配置JVM參數 -XX:+HeapDumpOnOutOfMemoryError ,讓虛擬機在內存溢出的時候dump出內存快照,也可以使用 jmap -dump:format=b,file=./dumpresult.hprof 65684 命令隨時dump出內存快照。

  打開MAT后,點擊“Open a Heap Dump”選擇dump文件,會彈出如下界面:

  

  選擇“Leak Suspects Report”生成內存泄漏分析報告:

  

  MAT會以餅圖的形式列出發生內存溢出時候,堆內存中占用內存最大的的幾個對象。點擊“Leak Suspects”查看內存泄漏分析報告:

  

  

  MAT分析結果認為導致內存泄漏的原因有兩點,問題1大意是0xff993af0 http-nio-8080-exec-1這個線程持有的本地變量占用了50.20%的內存,點擊Detail可以查看具體的分析結果:

  

  分析結果中列出了內存中對象統計結果,按照類進行統計的結果,可以看到有此時內存中共有com.demo.ssm.entity.User類的對象50428個,這些對象的保留堆大小為15,330,112kb。同時0xfe990000的這個Object中保存了56*20=1120個User對象,而這個Object是被0xffa65ff0這個ArrayList引用的,該Object和ArrayList占用堆內存50.18%。按照這些信息,排查代碼中向ArrayList中添加User對象的操作,可以找出內存溢出的原因。

  關於MAT的使用要點,可以參考:https://eclipsesource.com/blogs/2013/01/21/10-tips-for-using-the-eclipse-memory-analyzer/

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM