文章分類:Java編程
一直沒有做過jvm監控, 總以爲要找些專門的工具才能做jvm監控, 如jprofile之類的工具, 但這類工具都是收費的。
經過查找,發現其實sun的jdk中就帶有這類工具,從jdk5開始命令行有了jstat,jps,jstatd,圖形監控有了jconsole;而到了jdk6,命令有了jmap, jinfo, jstack,圖形有了jvisualvm。經過簡單試用,這些命令+圖形工具 已經足夠強大, 能滿足一般的監控要求了,如對各類內存、垃圾回收、線程狀態的監控。
命令:
以下轉自:http://hqman.iteye.com/blog/167796
jstatd
啓動jvm監控服務。它是一個基於rmi的應用,向遠程機器提供本機jvm應用程序的信息。默認端口1099。
實例:jstatd -J-Djava.security.policy=my.policy
my.policy文件需要自己建立,內如如下:
grant codebase "file:$JAVA_HOME/lib/tools.jar" {
permission java.security.AllPermission;
};
這是安全策略文件,因爲jdk對jvm做了jaas的安全檢測,所以我們必須設置一些策略,使得jstatd被允許作網絡操作
jps
列出所有的jvm實例
實例:
jps
列出本機所有的jvm實例
jps 192.168.0.77
列出遠程服務器192.168.0.77機器所有的jvm實例,採用rmi協議,默認連接端口爲1099
(前提是遠程服務器提供jstatd服務)
輸出內容如下:
jones@jones:~/data/ebook/java/j2se/jdk_gc$ jps
6286 Jps
6174 Jstat
jconsole
一個圖形化界面,可以觀察到java進程的gc,class,內存等信息。雖然比較直觀,但是個人還是比較傾向於使用jstat命令(在最後一部分會對jstat作詳細的介紹)。
jinfo(linux下特有)
觀察運行中的java程序的運行環境參數:參數包括Java System屬性和JVM命令行參數
實例:jinfo 2083
其中2083就是java進程id號,可以用jps得到這個id號。
輸出內容太多了,不在這裏一一列舉,大家可以自己嘗試這個命令。
jstack(linux下特有)
可以觀察到jvm中當前所有線程的運行情況和線程當前狀態
jstack 2083
輸出內容如下:
jmap(linux下特有,也是很常用的一個命令)
觀察運行中的jvm物理內存的佔用情況。
參數如下:
-heap:打印jvm heap的情況
-histo:打印jvm heap的直方圖。其輸出信息包括類名,對象數量,對象佔用大小。
-histo:live :同上,但是隻答應存活對象的情況
-permstat:打印permanent generation heap情況
命令使用:
jmap -heap 2083
可以觀察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的內存使用情況
輸出內容:
jmap -histo 2083 | jmap -histo:live 2083
可以觀察heap中所有對象的情況(heap中所有生存的對象的情況)。包括對象數量和所佔空間大小。
輸出內容:
寫個腳本,可以很快把佔用heap最大的對象找出來,對付內存泄漏特別有效。
jstat
最後要重點介紹下這個命令。
這是jdk命令中比較重要,也是相當實用的一個命令,可以觀察到classloader,compiler,gc相關信息
具體參數如下:
-class:統計class loader行爲信息
-compile:統計編譯行爲信息
-gc:統計jdk gc時heap信息
-gccapacity:統計不同的generations(不知道怎麼翻譯好,包括新生區,老年區,permanent區)相應的heap容量情況
-gccause:統計gc的情況,(同-gcutil)和引起gc的事件
-gcnew:統計gc時,新生代的情況
-gcnewcapacity:統計gc時,新生代heap容量
-gcold:統計gc時,老年區的情況
-gcoldcapacity:統計gc時,老年區heap容量
-gcpermcapacity:統計gc時,permanent區heap容量
-gcutil:統計gc時,heap情況
-printcompilation:不知道幹什麼的,一直沒用過。
jstat也提供遠程能力,
一般比較常用的幾個參數是:
jstat -class 2083 1000 10 (每隔1秒監控一次,一共做10次)
輸出內容含義如下:
Loaded | Number of classes loaded. |
Bytes | Number of Kbytes loaded. |
Unloaded | Number of classes unloaded. |
Bytes | Number of Kbytes unloaded. |
Time | Time spent performing class load and unload operations. |
jstat -gc 2083 2000 20(每隔2秒監控一次,共做10)
輸出內容含義如下:
S0C | Current survivor space 0 capacity (KB). |
EC | Current eden space capacity (KB). |
EU | Eden space utilization (KB). |
OC | Current old space capacity (KB). |
OU | Old space utilization (KB). |
PC | Current permanent space capacity (KB). |
PU | Permanent space utilization (KB). |
YGC | Number of young generation GC Events. |
YGCT | Young generation garbage collection time. |
FGC | Number of full GC events. |
FGCT | Full garbage collection time. |
GCT | Total garbage collection time. |
輸出內容:
圖形:
visualvm
http://www.iteye.com/topic/516447
如果是本地監控,則可以直接在本地的 窗口中看到java應用程序。雙擊點開即可打開監控窗口。
我們再看一下圖1,左邊的窗口中,第二個節點—Remote,它可以用來操作遠程機器。遠程機器需要啓動一個daemon:jstatd
1、遠程機器啓動jstatd
1.1、首先需要準備一個java.policy文件,保存到如/home/admin/jstatd.java.policy
grant codebase "file:${java.home}/../lib/tools.jar" { permission java.security.AllPermission; }; |
1.2、啓動jstatd
jstatd -J-Djava.security.policy=/home/admin/jstatd.java.policy -J-Djava.rmi.server.logCalls=true |
1.3、同時需要執行一個命令看看(linux需要)
Hostname –i 如果顯示是127.0.0.1,則需要修改/etc/hosts文件,去掉對本機名的配置,讓本機名解析到它的IP地址,如10.20.131.214 |
2、連接遠程機器
(圖8)
3、點擊OK,看到會連接到遠程機器,並顯示出它下面的java進程。
jconsole
http://www.blogjava.net/beansoft/archive/2006/12/13/87494.html
監控本地應用
首先就是啓動您要監控的應用, 例如我用 JDK 1.6 來啓動了 Tomcat, 或者 Eclipse 也可以, 可以在任務管理器(Ctrl+Alt+Del可以調出來, 或者在任務欄點擊右鍵)裏看到進程ID, 例如我這裏是 6132.
接着在 JDK 安裝目錄中(<JDK_HOME>/bin/jconsole.exe)啓動 jconsole.exe (雙擊或者在 cmd 裏面敲入 jconsole), 主界面會提示您建立一個新連接:
可以看到進程ID, 選擇它, 然後點擊"連接". 這些 ID 必須都是用 JDK 1.6 的 java.exe 啓動的, 否則在列表裏看不到.
JConsle 能監控內存,線程,類的數目和CPU然後點擊各個 Tab 可以看到詳細的輸出, 詳細的輸出包括:
內存: 堆/非堆, 峯值, 內存的各個部分, 例如 Perm, Eden 等的大小曲線圖.
線程: 峯值, 所有線程的列表, 堆棧跟蹤(哪個對象中的線程)等. 還可以強制執行GC.
類: 峯值, 類總數曲線圖.
MBean: 一些 JVM 參數的詳細 MBean 信息.
監控遠程進程
首先需要在運行的應用上啓用遠程管理, 參數如下(簡單期間就不加用戶驗證了):
java -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar ../demo/jfc/Java2D/Java2Demo.jar
然後連接的時候選擇遠程進程, 地址輸入:
localhost:1090
即可.當然在別的電腦上(一般是局域網)可以輸入那個電腦的IP.
綜述: 使用 JConsole 可以簡單的監控 Server 狀態, 但是本身要佔一定的資源, 不過 JVM 自帶的監控, 理論上講應該是佔資源很小很小的, 可以用它來方便的瞭解 Web 服務器應用進程的狀態. 如果要調優應用, 還是使用 JProfiler 等工具更好一些, 當然它們佔的資源也更大.
a)使用 jps 查看遠端機器有哪些 JVM 進程在使用當中,命令如下:
jps 172.25.1.24 // 遠端機器的 IP 地址或名稱
屏幕輸入如下:
13686 Jstatd
14115 XXXJavaServer
15117 Jserver
b)從上面可以看到遠端機器的 Jstatd 進程已經啓動起來了。我們就可以使用 jstat 對相關進程的具體情況進行查看。
Jstat 命令用法如下:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
解釋如下:
Option 包括以下選項:
-class
-compiler
-gc
-gccapacity
-gccause
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-printcompilation
Vmid 就是 jps 查看到的進程 id ,如上 Jserver 的進程 id 是 15117 。
Interval 是時間間隔,單位爲毫秒, 1000 就是一秒。
Count 就是需要查看的次數。
例子假設我們需要查看 172.25.1.24 機器 vmid 爲 15117 的 gc 的情況,可以輸入下面的命令:
jstat -gc [email protected] 1000 3
然後你能看到四行信息(一行爲 title ,剩下的就是你要的信息了),仔細看看就可以發現很多信息的了。
c) jstat還有一個可視化的監控包, 叫做jvmstat ,可以從sun的主頁下載到。下載好了後,解壓到任意目錄。
執行 visualgc <pid> ,其實命令跟jstat很像,也可以監控到遠程主機。然後就可以看到可視化的監控窗口。還挺酷的。