一、常用命令
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/