監控GC的工具分為2種:命令行工具和圖形工具;
常用的命令行工具有:
注:下面的命令都在JAVA_HOME/bin中,是java自帶的命令。如果您發現無法使用,請直接進入Java安裝目錄調用或者先設置Java的環境變量,一個簡單的辦法為:直接運行命令 export PATH=$JAVA_HOME/bin:$PATH;
另外,一般的,在Linux下,下面的命令需要sudo權限,在windows下,部分命令的部分選項不能使用。
JVM性能調優監控工具jps、jstack、jmap、jhat、jstat、hprof使用詳解
1、jps
查詢正在運行的JVM進程,常用的參數為:
-q:只輸出LVMID,省略主類的名稱
-m:輸出虛擬機進程啟動時傳給主類main()函數的參數
-l:輸出主類的全類名,如果進程執行的是Jar包,輸出Jar路徑
-v:輸出虛擬機進程啟動時JVM參數
命令格式:jps [option] [hostid]
一個簡單的例子:
在上圖中,有一個vid為309的apache進程在提供web服務。
圖形化界面JConsole啟動后,將自動搜索本機運行的jvm進程,不需要jps命令來查詢指定
2、jstat
jstat可以實時顯示本地或遠程JVM進程中類裝載、內存、垃圾收集、JIT編譯等數據(如果要顯示遠程JVM信息,需要遠程主機開啟RMI支持)。
如果在服務啟動時沒有指定啟動參數-verbose:gc,則可以用jstat實時查看gc情況。
命令格式:jstat [option vmid [interval[s|ms] [count]]]
參數解釋:
Options — 選項,我們一般使用 -gcutil 查看gc情況
vmid — VM的進程號,即當前運行的java進程號
interval– 間隔時間,單位為秒或者毫秒
count — 打印次數,如果缺省則打印無數次
-gcutil: 監視內容與-gc基本相同,不同的是這里顯示的是已占用的百分比,如S0為86.53,代表着S0區已使用了86.53%
>jstat -gc 1532
>jstat -gc 1532 1000 5
>jstat -gcutil 1532 1000 5
jstat有如下選項:
-class:
監視類裝載、卸載數量、總空間及類裝載所耗費的時間
-gc:
監聽Java堆狀況,包括Eden區、兩個Survivor區、老年代、永久代等的容量,以用空間、GC時間合計等信息
-gccapacity:
監視內容與-gc基本相同,但輸出主要關注java堆各個區域使用到的最大和最小空間
-gcutil:
監視內容與-gc基本相同,但輸出主要關注已使用空間占總空間的百分比
-gccause:
與-gcutil功能一樣,但是會額外輸出導致上一次GC產生的原因
-gcnew:
監視新生代GC狀況
-gcnewcapacity:
監視內同與-gcnew基本相同,輸出主要關注使用到的最大和最小空間
-gcold:
監視老年代GC情況
-gcoldcapacity:
監視內同與-gcold基本相同,輸出主要關注使用到的最大和最小空間
-gcpermcapacity:
輸出永久代使用到最大和最小空間
-compiler:
輸出JIT編譯器編譯過的方法、耗時等信息
-printcompilation:
輸出已經被JIT編譯的方法
一些術語的中文解釋:
S0C:S0區容量(S1區相同,略)
S0U:S0區已使用
EC:E區容量
EU:E區已使用
OC:老年代容量
OU:老年代已使用
PC:Perm容量
PU:Perm區已使用
YGC:Young GC(Minor GC)次數
YGCT:Young GC總耗時
FGC:Full GC次數
FGCT:Full GC總耗時
GCT:GC總耗時
實例使用:
[root@localhost bin]# jstat -gcutil 25444
S0 S1 E O P YGC YGCT FGC FGCT GCT
11.63 0.00 56.46 66.92 98.49 162 0.248 6 0.331 0.579
實例使用2:(25444是java的進程號,ps -ef | grep java)
[root@localhost bin]# jstat -gcutil 25444 1000 5
S0 S1 E O P YGC YGCT FGC FGCT GCT
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
ps -ef|grep jboss
jstat -gcutil $pid
S0 S1 E O P YGC YGCT FGC FGCT GCT
74.79 0.00 95.15 0.86 37.35 2 0.112 0 0.000 0.112
3、jstack
用於生成當前JVM的所有線程快照,線程快照是虛擬機每一條線程正在執行的方法,目的是定位線程出現長時間停頓的原因。
-F:當正常輸出的請求不被響應時,強制輸出線程堆棧
-l:除堆棧外,顯示關於鎖的附加信息
-m:如果調用到本地方法的話,可以顯示C/C++的堆棧
命令格式:jstack [option] vmid
4、jmap
jmap用來查看堆內存使用狀況,一般結合jhat使用。
用於顯示當前Java堆和永久代的詳細信息(如當前使用的收集器,當前的空間使用率等)
-dump:生成java堆轉儲快照
-heap:顯示java堆詳細信息(只在Linux/Solaris下有效)
-F:當虛擬機進程對-dump選項沒有響應時,可使用這個選項強制生成dump快照(只在Linux/Solaris下有效)
-finalizerinfo:顯示在F-Queue中等待Finalizer線程執行finalize方法的對象(只在Linux/Solaris下有效)
-histo:顯示堆中對象統計信息
-permstat:以ClassLoader為統計口徑顯示永久代內存狀態(只在Linux/Solaris下有效)
命令格式:jmap [option] vmid
其中前面3個參數最重要,如:
查看對詳細信息:jmap -heap 309
生成dump文件: jmap -dump:file=./test.prof 309
查看當前堆中對象統計信息: jmap -histo 309:
該命令顯示3列,分別為對象數量,對象大小,對象名稱,通過該命令可以查看是否內存中有大對象;
用jmap把進程內存使用情況dump到文件中,再用jhat分析查看
jmap進行dump命令格式如下:
jmap -dump:format=b,file=dumpFileName pid
我一樣地對上面進程ID為21711進行Dump:
root@ubuntu:/# jmap -dump:format=b,file=/tmp/dump.dat 21711
Dumping heap to /tmp/dump.dat ...
Heap dump file created
5、jhat
用於分析使用jmap生成的dump文件,是JDK自帶的工具,使用方法為: jhat -J -Xmx512m [file]
不過jhat沒有mat好用,推薦使用mat(Eclipse插件: http://www.eclipse.org/mat ),mat速度更快,而且是圖形界面。