最近有些空閑的時(shí)間,看了一些JVM內(nèi)存管理方面的知識(shí),由于JDK自帶了一些工具用于Java的故障排除,性能分析,監(jiān)控和管理等。從本章開始以及后續(xù)的文章將進(jìn)行這方面的實(shí)踐活動(dòng)。
一、JDK監(jiān)控類工具
注:文章中提及的工具均在java安裝目錄的/bin目錄下
[1] jps -- Java Virtual Machine Process Status Tool
jvm進(jìn)程狀態(tài)工具,可以列出本機(jī)所有java進(jìn)程的pid。該命令類似于linux的ps命令哦。
1.概要
jps [ options ] [ hostid ]
options
-q 禁止輸出類的名稱,JAR文件的名稱,傳遞給方法的參數(shù),主要產(chǎn)生本地VM標(biāo)識(shí)符列表(即只輸出pid列表);
-m 輸出傳遞給main方法的參數(shù),嵌入式JVM可能輸出為空;
-l 輸出應(yīng)用程序主類的全包名或者應(yīng)用程序jar文件的全路徑名;
-v 輸出傳遞給JVM的參數(shù);
-V 輸出通過flag文件傳遞到JVM中的參數(shù)(.hotspotrc文件或由-XX:Flags=<filename>指定的參數(shù));
-Joption 傳遞參數(shù)到vm,例如:-J-Xms48m
hostid
[protocol:][[//]hostname][:port][/servername]
2.輸出格式
lvmid [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]
3.示例
(1) jps 僅顯示進(jìn)程id,主類名

(2) jps -q 僅顯示進(jìn)程id

(3)jps -l 輸出完全的包名,主類名,jar完全路徑名

(4)jps -v 顯示jvm參數(shù)(如果對(duì)jvm參數(shù)不熟悉,請(qǐng)看《深入JVM內(nèi)幕》)

jps –l 127.0.0.1 輸出127.0.0.1機(jī)器上的java進(jìn)程,顯示完全的包名,主類名,jar完全路徑
注意:127.0.0.1主機(jī)要啟動(dòng)jstatd (關(guān)于如何啟動(dòng)jstatd,請(qǐng)參見jstated)

參考:
http://download.oracle.com/javase/6/docs/technotes/tools/share/jps.html
[2] Jstated --Virtual Machine jstat Daemon(虛擬機(jī)jstat守護(hù)進(jìn)程)
jstatd工具是一個(gè)RMI服務(wù)器應(yīng)用程序,用來監(jiān)視Java虛擬機(jī)(JVM)的創(chuàng)建和終結(jié),它提供了一個(gè)接口,允許遠(yuǎn)程監(jiān)控工具連接到運(yùn)行在本地主機(jī)上的JVM。
jstatd 服務(wù)需要本地存在一個(gè)RMI注冊(cè). jstatd服務(wù)將嘗試依附于RMI注冊(cè),使用默認(rèn)端口上,或者用-p指定的端口上. 假如rmi注冊(cè)沒有找到,jstatd應(yīng)用將會(huì)創(chuàng)建一個(gè)使用指定端口或默認(rèn)端口. 如果jstatd的參數(shù)指定了-nr選項(xiàng),那么創(chuàng)建一個(gè)內(nèi)部的RMI注冊(cè)是被禁止的。
1.概要
jstatd [ options ]
options
-nr 當(dāng)一個(gè)存在的RMI注冊(cè)表未被找到時(shí),jstatd將不試圖創(chuàng)建一個(gè)內(nèi)部的RMI注冊(cè)表;
-p port 期望的RMI注冊(cè)端口號(hào),或者自己創(chuàng)建的RMI注冊(cè)的端口號(hào);
-n rminame 綁定在RMI注冊(cè)表中的遠(yuǎn)程RMI對(duì)象的名稱,默認(rèn)為JstatRemoteHost;假如啟動(dòng)多個(gè)jstatd進(jìn)程,那么就需要用這個(gè)參數(shù)指定名字以區(qū)分.
-Joption 傳遞參數(shù)到vm,例如:-J-Xms48m
2.securty
jstatd服務(wù)只能在合適的內(nèi)部訪問權(quán)限下啟動(dòng). 因此jstatd進(jìn)程必須用啟動(dòng)JVMs的同用戶啟動(dòng). 一些用戶的權(quán)限,如root用戶擁有該機(jī)所有JVMs的訪問權(quán)限,可以啟動(dòng)jstatd,但是會(huì)引入額外的安全問題.jstatd服務(wù)沒有為客戶端提供任何驗(yàn)證. 所以他會(huì)把jstatd進(jìn)程訪問的jvms暴露給網(wǎng)絡(luò)中所有的用戶. 啟動(dòng)jstatd進(jìn)程的時(shí)候需要考慮一下,你的網(wǎng)絡(luò)是否安全,特別是在產(chǎn)品環(huán)境中.
在jstatd服務(wù)啟動(dòng)的時(shí)候引入一個(gè)policy文件將不會(huì)有任何安全的異常.

grant codebase "file:${java.home}/../lib/tools.jar"
{

permission java.security.AllPermission;

};

將以上內(nèi)容保存到名為jstatd.all.policy的當(dāng)前目錄文件中
然后啟動(dòng)jstatd
jstatd -J-Djava.security.policy=jstatd.all.policy
3.示例
(1)使用內(nèi)部RMI注冊(cè)表
jstatd -J-Djava.security.policy=jstatd.all.policy (默認(rèn)端口為1099)
jps –l 127.0.0.1

(2)使用外部RMI注冊(cè)表
rmiregistry 2020&
jstatd -J-Djava.security.policy=all.policy -p 2020
jps –l localhost:2020 (等價(jià)于遠(yuǎn)程監(jiān)控訪問)
參考:http://download.oracle.com/javase/6/docs/technotes/tools/share/jstatd.html[3] jstat - Java Virtual Machine Statistics Monitoring Tool
主要利用JVM內(nèi)建的指令對(duì)Java應(yīng)用程序的資源和性能進(jìn)行實(shí)時(shí)的命令行的監(jiān)控,包括了對(duì)Heap size和垃圾回收狀況的監(jiān)控。
概述
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
參數(shù)
generalOption(常規(guī)選項(xiàng))
一個(gè)常規(guī)命令行選項(xiàng)(-help, -options, or -version)。如果你指定了常規(guī)選項(xiàng)中的一個(gè),您就不能指定任何其他的選項(xiàng)或者參數(shù)。
outputOptions
一個(gè)或多個(gè)輸出選項(xiàng),由單一的statOption構(gòu)成,加上-t、-h和-Joptions。
vmid
虛擬機(jī)標(biāo)識(shí)符,一個(gè)指向目標(biāo)jvm的字符串,一般語法如下:
[protocol:][//]lvmid[@hostname[:port]/servername]
Interval
采樣間隔單位,秒(S)或毫秒(ms)。默認(rèn)單位是毫秒,必須為正整數(shù)。
count
樣品數(shù)量。默認(rèn)值是無限的,必須為正整數(shù)。
generalOption詳細(xì)說明
-help
顯示幫助信息
-version
顯示版本信息
-options
顯示統(tǒng)計(jì)選項(xiàng)列表。參看后面的output options一節(jié)。
如果你未指定常規(guī)選型,那么你就可以指定輸出選項(xiàng)了。輸出選項(xiàng)確定jstat的輸出內(nèi)容和格式,并且由單一的statOption構(gòu)成,再加上其它輸出選項(xiàng)(- h,- t和- J)。statOption必須放在第一位。
輸出的格式為表,列用空格隔開。帶有標(biāo)題的標(biāo)題行用來描述列。使用-h來設(shè)置標(biāo)題顯示的頻次。列標(biāo)題名在不同的選項(xiàng)之間通常是一致的。通常情況下,如果兩個(gè)選項(xiàng)提供具有相同名稱的列,那么這兩個(gè)列的數(shù)據(jù)源是相同的。
使用-t選項(xiàng)顯示一個(gè)時(shí)間戳列,標(biāo)注的時(shí)間戳將作為輸出的第一列。當(dāng)目標(biāo)jvm啟動(dòng)后,時(shí)間戳列記錄了消耗的時(shí)間,以秒來進(jìn)行刻畫。
使用間隔和計(jì)數(shù)參數(shù),以確定jstat輸出的頻次和次數(shù)。
outputOptions詳細(xì)說明
-statOption
class 類加載器行為信息的統(tǒng)計(jì)
compiler 編譯器行為信息的統(tǒng)計(jì);
gc 堆的垃圾收集行為信息的統(tǒng)計(jì);
gccapacity 各代(新生代、舊生代、持久代)的容量以及它們相應(yīng)空間信息的統(tǒng)計(jì);
gccause 垃圾收集統(tǒng)計(jì)匯總(與 –gcutil相同),包括過去和當(dāng)前垃圾收集事件的成因;
gcnew 對(duì)新生代行為信息的統(tǒng)計(jì);
gcnewcapacity 對(duì)新生代的大小以及它們相應(yīng)的空間的統(tǒng)計(jì);
gcold 對(duì)舊生代以及持久代行為信息的統(tǒng)計(jì);
gcoldcapacity 舊生代大小信息的統(tǒng)計(jì);
gcpermcapacity 持久代大小信息的統(tǒng)計(jì);
gctuil 垃圾收集統(tǒng)計(jì)匯總;
printcompilation 編譯方法統(tǒng)計(jì);
-h n
表示每n個(gè)樣本(輸出行)顯示一個(gè)列標(biāo)題,其中n是正整數(shù),默認(rèn)值是0。列標(biāo)題要顯示在上述樣本數(shù)據(jù)的第一行中。
-t n
表示時(shí)間戳列作為輸出的第一列。時(shí)間戳?xí)r間是自目標(biāo)jvm開始的時(shí)間。
-JjavaOption
傳遞javaOption給java程序啟動(dòng)器。例如,-JXms48m 設(shè)置為48m的內(nèi)存啟動(dòng)。
statOptions and Output
下列表格匯總了針對(duì)每個(gè)statOption的jstat輸出的列;
-class 選項(xiàng)
列 |
描述 |
Loaded |
加載類的數(shù)量 |
Bytes |
加載的字節(jié)數(shù) |
Unloaded |
卸載類的數(shù)量 |
Bytes |
卸載字節(jié)數(shù) |
Time |
執(zhí)行加載和卸載操作花費(fèi)的時(shí)間 |
-compiler 選項(xiàng)
列 |
描述 |
Compiled |
執(zhí)行的編譯任務(wù)數(shù)量 |
Failed |
編譯任務(wù)失敗的數(shù)量 |
Invalid |
無效的編譯任務(wù)的數(shù)量 |
Time |
執(zhí)行編譯任務(wù)所消耗的時(shí)間 |
FailedType |
最后編譯失敗的編譯類型 |
FailedMethod |
最后編譯失敗的類名與方法 |
-gc 選項(xiàng)
列 |
描述 |
S0C |
新生代survibor space 0 區(qū)(S0)的容量(KB) |
S1C |
新生代survibor space 1 區(qū)(S1)的容量(KB) |
S0U |
S0使用(KB) |
S1U |
S1使用(KB) |
EC |
新生代Eden space容量(KB) |
EU |
Eden space使用(KB) |
OC |
舊生代的容量(KB) |
OU |
舊生代使用(KB) |
PC |
持久代容量(KB) |
PU |
持久代使用(KB) |
YGC |
從應(yīng)用程序啟動(dòng)到采樣時(shí)發(fā)生 Young GC 的次數(shù) |
YGCT |
Young GC 所用的時(shí)間(單位秒) |
FGC |
Full GC 次數(shù) |
FGCT |
Full GC 所用的時(shí)間(單位秒) |
GCT |
垃圾回收的總時(shí)間(單位秒) |
-gcutil 選項(xiàng)
列 |
描述 |
S0 |
Heap上Survivor space 0 區(qū)已使用空間的百分比 |
S1 |
Survivor space 1 區(qū)已使用空間的百分比 |
E |
Eden space 區(qū)已使用空間的百分比 |
O |
Old space 區(qū)已使用空間的百分比 |
P |
Perm space 區(qū)已使用空間的百分比 |
YGC |
從應(yīng)用程序啟動(dòng)到采樣時(shí)發(fā)生 Young GC 的次數(shù) |
YGCT |
Young GC 所用的時(shí)間(單位秒) |
FGC |
Full GC 次數(shù) |
FGCT |
Full GC 所用的時(shí)間(單位秒) |
GCT |
垃圾回收的總時(shí)間(單位秒) |
|
|
其他選項(xiàng)的輸出,請(qǐng)查看reference
例子
(1)使用gc選項(xiàng)
在使用gc選項(xiàng)之前,首先要通過jps獲得jvm的vmid,如下:
從圖中可以看到,有3個(gè)java進(jìn)程,2500是一個(gè)tomcat進(jìn)程,tomcat對(duì)應(yīng)一個(gè)jvm實(shí)例。
通過jstat –gc 2500我們能夠看到如下信息,S0、S1、Eden space的容量以及使用量,舊生代、持久代的容量以及使用量,Younc GC和Full GC的次數(shù)以及GC的時(shí)間,GC總時(shí)間。

(2)使用gcutil
對(duì)vmid為2500的jvm進(jìn)行采樣,采樣的數(shù)量為10,時(shí)間間隔為10秒。
從上圖中我們看到,舊生代、持久代的使用率很高,尤其是持久代最高已經(jīng)達(dá)到99.78%,因此,在內(nèi)容容量許可的情況下,需要對(duì)heap的持久代以及舊生代的內(nèi)存進(jìn)行調(diào)整。
紅色的框表示,在兩次采樣期間,JVM發(fā)生了3此Young GC,Survivor Space從56.41%降低到37.53%,Eden space由94.73%降低到10.63%。并且在GC期間,至少發(fā)生了一次從S1區(qū)到S0區(qū)的對(duì)象復(fù)制。
常駐內(nèi)存區(qū)(P-持久代)的使用率,始終停留在99%左右,說明常駐內(nèi)存沒有突變,比較正常。如果young gc和full gc能夠正常發(fā)生,而且都能有效回收內(nèi)存,常駐內(nèi)存區(qū)變化不明顯,則說明java內(nèi)存釋放情況正常,垃圾回收及時(shí),java內(nèi)存泄露的幾率就會(huì)大大降低。但也不能說明一定沒有內(nèi)存泄露。
posted on 2011-06-20 11:38
zhangxl 閱讀(674)
評(píng)論(0) 編輯 收藏 所屬分類:
java tools