監控JVM工具
JDK內置工具使用
- jps(Java Virtual Machine Process Status Tool)
查看所有的jvm進程,包括進程ID,進程啟動的路徑等等。 - jstack(Java Stack Trace)
① 觀察jvm中當前所有線程的運行情況和線程當前狀態。
② 系統崩潰了?如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發生問題。
③ 系統hung住了?jstack工具還可以附屬到正在運行的java程序中,看到當時運行的java程序的java stack和native stack的信息, 如果現在運行的java程序呈現hung的狀態,jstack是非常有用的。 - jstat(Java Virtual Machine Statistics Monitoring Tool)
① jstat利用JVM內建的指令對Java應用程序的資源和性能進行實時的命令行的監控,包括了對進程的classloader,compiler,gc情況;
②監視VM內存內的各種堆和非堆的大小及其內存使用量,以及加載類的數量。 - jmap(Java Memory Map)
監視進程運行中的jvm物理內存的占用情況,該進程內存內,所有對象的情況,例如產生了哪些對象,對象數量;
- jinfo(Java Configuration Info)
觀察進程運行環境參數,包括Java System屬性和JVM命令行參數
</ul>
- jstat
#參數: -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:不知道干什么的,一直沒用過。
例如 -class:
#每隔1秒監控一次,一共做10次 jstat -class 17970 1000 10
#
[root@lq225 conf]# jstat -class 2058 1000 10 Loaded Bytes Unloaded Bytes Time 1697 3349.5 0 0.0 1.79 1697 3349.5 0 0.0 1.79 1697 3349.5 0 0.0 1.79 1697 3349.5 0 0.0 1.79 ...................................................
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.</pre>例如 -gc:
#每隔2秒監控一次,共20次 jstat -gc 2058 2000 20
#
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
8704.0 8704.0 805.5 0.0 69952.0 64174.5 174784.0 2644.5 16384.0 10426.7 2 0.034 0 0.000 0.034 8704.0 8704.0 805.5 0.0 69952.0 64174.5 174784.0 2644.5 16384.0 10426.7 2 0.034 0 0.000 0.034 8704.0 8704.0 805.5 0.0 69952.0 64174.5 174784.0 2644.5 16384.0 10426.7 2 0.034 0 0.000 0.034 .............................................一些術語的中文解釋:
S0C:年輕代中第一個survivor(幸存區)的容量 (字節) S1C:年輕代中第二個survivor(幸存區)的容量 (字節) S0U:年輕代中第一個survivor(幸存區)目前已使用空間 (字節) S1U:年輕代中第二個survivor(幸存區)目前已使用空間 (字節) EC:年輕代中Eden(伊甸園)的容量 (字節) EU:年輕代中Eden(伊甸園)目前已使用空間 (字節) OC:Old代的容量 (字節) OU:Old代目前已使用空間 (字節) PC:Perm(持久代)的容量 (字節) PU:Perm(持久代)目前已使用空間 (字節) YGC:從應用程序啟動到采樣時年輕代中gc次數 YGCT:從應用程序啟動到采樣時年輕代中gc所用時間(s) FGC:從應用程序啟動到采樣時old代(全gc)gc次數 FGCT:從應用程序啟動到采樣時old代(全gc)gc所用時間(s) GCT:從應用程序啟動到采樣時gc用的總時間(s) NGCMN:年輕代(young)中初始化(最小)的大小 (字節) NGCMX:年輕代(young)的最大容量 (字節) NGC:年輕代(young)中當前的容量 (字節) OGCMN:old代中初始化(最小)的大小 (字節) OGCMX:old代的最大容量 (字節) OGC:old代當前新生成的容量 (字節) PGCMN:perm代中初始化(最小)的大小 (字節) PGCMX:perm代的最大容量 (字節) PGC:perm代當前新生成的容量 (字節) S0:年輕代中第一個survivor(幸存區)已使用的占當前容量百分比 S1:年輕代中第二個survivor(幸存區)已使用的占當前容量百分比 E:年輕代中Eden(伊甸園)已使用的占當前容量百分比 O:old代已使用的占當前容量百分比 P:perm代已使用的占當前容量百分比 S0CMX:年輕代中第一個survivor(幸存區)的最大容量 (字節) S1CMX:年輕代中第二個survivor(幸存區)的最大容量 (字節) ECMX:年輕代中Eden(伊甸園)的最大容量 (字節) DSS:當前需要survivor(幸存區)的容量 (字節)(Eden區已滿) TT: 持有次數限制 MTT : 最大持有次數限制</pre>例如 -gcutil :
#每隔1秒監控一次,共10次 jstat -gcutil 2058 1000 10
#
[root@lq225 conf]# jstat -gcutil 2058 1000 10 S0 S1 E O P YGC YGCT FGC FGCT GCT
9.25 0.00 96.73 1.51 63.64 2 0.034 0 0.000 0.034 9.25 0.00 96.73 1.51 63.64 2 0.034 0 0.000 0.034 9.25 0.00 96.73 1.51 63.64 2 0.034 0 0.000 0.034 9.25 0.00 96.73 1.51 63.64 2 0.034 0 0.000 0.034</pre></span></li>- jmap</strong>
#參數 -dump:[live,]format=b,file=<filename> 使用hprof二進制形式,輸出jvm的heap內容到文件=. live子選項是可選的,假如指定live選項,那么只輸出活的對象到文件. -finalizerinfo 打印正等候回收的對象的信息. -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情況. -histo[:live] 打印每個class的實例數目,內存占用,類全名信息. VM的內部類名字開頭會加上前綴”*”. 如果live子參數加上后,只統計活的對象數量. -permstat 打印classload和jvm heap長久層的信息. 包含每個classloader的名字,活潑性,地址,父classloader和加載的class數量. 另外,內部String的數量和占用內存數也會打印出來. -F 強迫.在pid沒有相應的時候使用-dump或者-histo參數. 在這個模式下,live子參數無效. -h | -help 打印輔助信息 -J 傳遞參數給jmap啟動的jvm. pid 需要被打印配相信息的java進程id.
例如 -histo :
jmap -histo 2058
#
num #instances #bytes class name
1: 206 3585312 [I 2: 19621 2791880 <constMethodKlass> 3: 19621 2520048 <methodKlass> 4: 21010 2251616 [C ............................................................</pre>例如 -dump:
#生成的文件可以使用jhat工具進行分析,在OOM(內存溢出)時,分析大對象,非常有用 jmap -dump:live,format=b,file=data.hprof 2058
通過使用如下參數啟動JVM,也可以獲取到dump文件:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid<pid>.hprof
如果在虛擬機中導出的heap信息文件可以拿到WINDOWS上進行分析,可以查找諸如內存方面的問題,可以這么做:
jhat data.hprof
執行成功后,訪問http://localhost:7000即可查看內存信息。(首先把7000端口打開)</pre></span></li>
- jinfo</strong>
#查看java進程的配置信息 jinfo 2058
#
Attaching to process ID 2058, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.0-b56 Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment project.name = Amoeba-MySQL java.vm.version = 24.0-b56 sun.boot.library.path = /usr/local/java/jdk1.7/jre/lib/amd64 ................................................
查看2058的MaxPerm大小可以用
jinfo -flag MaxPermSize 2058
#
-XX:MaxPermSize=100663296</pre></span></li>
- jps</strong>
#列出系統中所有的java進程 jps
#
2306 Bootstrap 3370 Jps 2058 xxxxxxxxx</pre></span></li> </ul>
使用visualvm監控tomcat
- 修改catalina.sh,添加下面一行:
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote=true -Djava.rmi.server.hostname=192.168.55.255 -Dcom.sun.management.jmxremote.port=8086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
注意點:
1、用hostname -i 查看是否為127.0.01,如果是,則必須配置-Djava.rmi.server.hostname為本機IP。
2、檢查防火墻(iptables)是否開啟,以及是否開放jmxremote.port所指定的端口。</pre>
</li> </ul>
- jmap</strong>