Linux監控JVM常用命令解析

在開發中,隨着對底層的不斷學習中,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命令行參數

具體命令使用:

jstat

generalOption

-help 顯示幫助信息。
-version 顯示版本信息
-options 顯示統計選項列表。

outputOptions 

#參數:
    -class:統計類裝載器的行爲
    -compiler:統計HotSpot Just-in-Time編譯器的行爲
    -gc:統計堆各個分區的使用情況
    -gccapacity:統計新生區,老年區,permanent區的heap容量情況 
    -gccause:統計最後一次gc和當前gc的原因
    -gcnew:統計gc時,新生代的情況 
    -gcnewcapacity:統計新生代大小和空間
    -gcold:統計老年代和永久代的行爲
    -gcoldcapacity:統計老年代大小 
    -gcpermcapacity:統計永久代大小 
    -gcutil:統計gc時,heap情況 
    -printcompilation:HotSpot編譯方法統計

-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 類加載數量
#Bytes  加載的大小(k) 
#Unloaded 類卸載的數量 
#Bytes 卸載的大小(k) 
#Time 時間花費在執行類加載和卸載操作

-compiler

Compiled Failed Invalid   Time   FailedType FailedMethod
     302      0       0     1.27          0
.....................................................
######################## 術語分隔符 ########################
#Compiled 編譯任務的執行次數
#Failed   編譯任務的失敗次數 
#Invalid  編譯任務無效的次數
#Time     編譯任務花費的時間
#FailedType 最後一次編譯錯誤的類型
#FailedMethod 最後一次編譯錯誤的類名和方法

-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 生還者區0 容量(KB)
#S1C 生還者區1 容量(KB)
#S0U 生還者區0 使用量(KB)
#S1U 生還者區1 使用量(KB)
#EC 伊甸園區容量(KB)
#EU 伊甸園區使用量(KB) 
#OC 老年區容量(KB)
#OU 老年區使用量(KB)
#PC 永久區容量(KB) 
#PU 永久區使用量(KB)
#YGC 新生代GC次數
#YGCT 新生代GC時間
#FGC full GC 事件的次數
#FGCT full GC的時間 
#GCT 總GC時間

-gccapacity

NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC
131072.0 131072.0 131072.0 13056.0 13056.0 104960.0   393216.0   393216.0   393216.0   393216.0  65536.0  65536.0  65536.0  65536.0      1     0
..........................................................................................................
######################## 術語分隔符 ########################
#NGCMN 最小新生代容量(KB)
#NGCMX 最大新生代容量(KB)
#NGC 當前新生代容量(KB)
#S0C 當前生存者0區容量(KB)
#S1C 當前生存者1區容量(KB)
#OGCMN 老年代最小容量(KB)
#OGCMX 老年代最大容量(KB)
#OGC 當前老年代容量(KB). 
#OC 當前老年代?Current old space capacity (KB). 
#PGCMN 永久區最小容量(KB)
#PGCMX 永久區最大容量(KB)
#PGC 當前永久區容量(KB). 
#PC 當前永久區?Current Permanent space capacity (KB). 
#YGC young GC事件的次數 
#FGC Full GC次數

-gccause

S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC
  0.00  99.84  12.76   0.92  46.23      1    0.016     0    0.000    0.016 unknown GCCause      No GC
................................................
######################## 術語分隔符 ########################
#S0 年輕代中第一個survivor(倖存區)已使用的佔當前容量百分比
#S1 年輕代中第二個survivor(倖存區)已使用的佔當前容量百分比
#E 年輕代中Eden(伊甸園)已使用的佔當前容量百分比
#O old代已使用的佔當前容量百分比
#P perm代已使用的佔當前容量百分比
#YGC 從應用程序啓動到採樣時年輕代中gc次數
#FGC 從應用程序啓動到採樣時old代(全gc)gc次數
#FGCT 從應用程序啓動到採樣時old代(全gc)gc所用時間(s)
#GCT 從應用程序啓動到採樣時gc用的總時間(s)
#LGCC 最後一次GC的原因
#GCC 當前GC的原因

例如 -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

jmap

#參數
    -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
............................................................

例如 -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端口打開)

jinfo

#查看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

jps

#列出系統中所有的java進程
  jps
#######################
2306 Bootstrap
3370 Jps 2058 xxxxxxxxx

一些術語的中文解釋

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 : 最大持有次數限制

使用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所指定的端口。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章