JAVA虛擬機性能監控和故障處理工具

1、JDK命令行工具簡介
全部的java開發人員都知道JDK的bin目錄下存放着編譯java須要的javac,以及運行java程序須要的java這兩個命令工具,可是不少人並無注意到,其實除了這兩個工具,該目錄下還有不少工具,這些工具其實爲咱們提供了不少方便且強大的功能,windows7系統64位jdk1.7/bin目錄下部分截圖:
下面是命令行監控的主要工具和用途:
名稱     做用
jps JVM Process Status Tool,現實指定系統內全部的HotSpot虛擬機進程 
jstat JVM Statistics Monitoring Tool,用於收集Hotspot虛擬機各個方面的運行參數 
jinfo Configuration Info for Java,現實虛擬機配置信息
jmap Memory map for java,生成虛擬機的內存轉儲快照
jhat JVM heap Dunp Browser,用於分析heapdump文件,他會創建一個HTTP/HTML服務,讓用戶可經過瀏覽器查看 
jstack Stack Track for java ,顯示虛擬機線程快照
一、jps
    jps用來查看基於HotSpot的JVM裏面中,全部具備訪問權限的Java進程的具體狀態, 包括進程ID,進程啓動的路徑及啓動參數等等,與unix上的ps相似,只不過jps是用來顯示java進程,能夠把jps理解爲ps的一個子集。 使用jps時,若是沒有指定hostid,它只會顯示本地環境中全部的Java進程;若是指定了hostid,它就會顯示指定hostid上面的java進程,不過這須要遠程服務上開啓了jstatd服務,能夠參看前面的jstatd章節來啓動jstad服務。
命令格式 :jps [ options ] [ hostid ] 
參數說明 :
-q 忽略輸出的類名、Jar名以及傳遞給main方法的參數,只輸出pid。
-m 輸出傳遞給main方法的參數,若是是內嵌的JVM則輸出爲null。
-l 輸出應用程序主類的完整包名,或者是應用程序JAR文件的完整路徑。
-v 輸出傳給JVM的參數。
-V 輸出經過標記的文件傳遞給JVM的參數(.hotspotrc文件,或者是經過參數-XX:Flags=<filename>指定的文件)。
-J 用於傳遞jvm選項到由javac調用的java加載器中,例如,「-J-Xms48m」將把啓動內存設置爲48M,使用-J選項能夠很是方便的向基於Java的開發的底層虛擬機應用程序傳遞參數。下面樣例均在linux的jdk1.7下測試。
使用樣例:
[root@tools138 ~]# jps
2897 Bootstrap
22558 Jps
[root@tools138 ~]# jps -l
2897 org.apache.catalina.startup.Bootstrap
22568 sun.tools.jps.Jps
[root@tools138 ~]# jps -v
2897 Bootstrap -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/tomcat/endorsed -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp
22578 Jps -Denv.class.path=/usr/java/jdk1.7.0/lib -Dapplication.home=/usr/java/jdk1.7.0 -Xms8m
 
二、jstat

Jstat用於監控基於HotSpot的JVM,對其堆的使用狀況進行實時的命令行的統計,使用jstat咱們能夠對指定的JVM作以下監控:html

- 類的加載及卸載狀況java

- 查看新生代、老生代及持久代的容量及使用狀況linux

- 查看新生代、老生代及持久代的垃圾收集狀況,包括垃圾回收的次數及垃圾回收所佔用的時間c++

- 查看新生代中Eden區及Survior區中容量及分配狀況等算法

jstat工具特別強大,它有衆多的可選項,經過提供多種不一樣的監控維度,使咱們能夠從不一樣的維度來了解到當前JVM堆的使用狀況。詳細查看堆內各個部分的使用量,使用的時候必須加上待統計的Java進程號,可選的不一樣維度參數以及可選的統計頻率參數。apache

命令格式:windows

jstat [ option vmid [interval][s|ms][count]]瀏覽器

option 參數以下面表格tomcat

Option Displays...
class 用於查看類加載狀況的統計
compiler 用於查看HotSpot中即時編譯器編譯狀況的統計
gc 用於查看JVM中堆的垃圾收集狀況的統計
gccapacity 用於查看新生代、老生代及持久代的存儲容量狀況
gccause 用於查看垃圾收集的統計狀況(這個和-gcutil選項同樣),若是有發生垃圾收集,它還會顯示最後一次及當前正在發生垃圾收集的緣由。
gcnew 用於查看新生代垃圾收集的狀況
gcnewcapacity 用於查看新生代的存儲容量狀況
gcold 用於查看老生代及持久代發生GC的狀況
gcoldcapacity 用於查看老生代的容量
gcpermcapacity 用於查看持久代的容量
gcutil 用於查看新生代、老生代及持代垃圾收集的狀況
printcompilation HotSpot編譯方法的統計
interval 和count 表明查詢次數和間隔。
使用樣例:
[root@tools138 ~]# jstat -class 2897
Loaded  Bytes  Unloaded  Bytes     Time  
 67431 113866.2    59850 98607.5    1884.07
 
[root@tools138 ~]# jstat -compiler  2897
Compiled Failed Invalid   Time   FailedType FailedMethod
    3782      1       0   507.88          1 org/apache/tomcat/util/IntrospectionUtils setProperty

 表示查詢系統進程爲2897的java程序gc,每100毫秒查詢一次,一共查詢十次,顯示結果每列的含義以下: 
列名 說明
S0C 新生代中Survivor space中S0當前容量的大小(KB)
S1C 新生代中Survivor space中S1當前容量的大小(KB)
S0U 新生代中Survivor space中S0容量使用的大小(KB)
S1U 新生代中Survivor space中S1容量使用的大小(KB)
EC Eden space當前容量的大小(KB)
EU Eden space容量使用的大小(KB)
OC Old space當前容量的大小(KB)
OU Old space使用容量的大小(KB)
PC Permanent space當前容量的大小(KB)
PU Permanent space使用容量的大小(KB)
YGC 從應用程序啓動到採樣時發生 Young GC 的次數
YGCT 從應用程序啓動到採樣時 Young GC 所用的時間(秒)
FGC 從應用程序啓動到採樣時發生 Full GC 的次數
FGCT 從應用程序啓動到採樣時 Full GC 所用的時間(秒)
GCT T從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC
其餘以gc開始的結果列跟gc選項結果列基本同樣,這裏不一一列舉了。
 
三、jinfo
jinfo能夠輸出並修改運行時的java 進程的opts。用處比較簡單,用於輸出JAVA系統參數及命令行參數。
命令格式:
jinfo [option] pid
使用樣例:
[root@tools138 ~]# jinfo  -flag  MaxNewSize  2897
-XX:MaxNewSize=18446744073709486080
 
四、jmap
jmap用於生成堆轉儲快照(通常稱爲heapdump或者dump文件)。固然也可其餘方法好比加參數-XX:+HeapDumpOnOutOfMemoryError參數,在虛擬機OOM異常的以後自動生成dump文件,也能夠經過-XX:+HeapDumpOnCtrlBreak參數則可使用Ctrl+Break鍵讓虛擬機生成dump文件。在前文《 JAVA虛擬機之3:CMS垃圾收集器》測試中就有生成。dump文件生成後可藉助jha、MAT( Eclipse Memory Analyzer tool)、IBM HeapAnalyzer來對dump分析。jmap不只能獲取dump還能夠查詢finalize執行隊列,java堆和永久代詳細信息,空間使用率,當前用的是什麼收集器等。
jmap -J-d64 -heap pid
命令格式:
       jmap [ option ] pid
參數說明:
-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子參數無效.
使用樣例:
jmap -dump:format=b,file=eclipse.bin
[root@tools138 ~]# jmap -dump:format=b,file=eclipse.bin  2897
Dumping heap to /root/eclipse.bin ...
Heap dump file created
 
五、jhat
jhat是sun提供的dump分析工具,上面講過度析dump的工具還有MAT( Eclipse Memory Analyzer tool)、IBM HeapAnalyzer等,通常這個命令不太用到,是由於分析dump是個既耗時又耗機器資源的過程,第二個緣由是這個工具比較簡陋,沒有MAT( Eclipse Memory Analyzer tool)、IBM HeapAnalyzer這些專業和強大。
命令格式:
jhat file
使用樣例:
防止影響服務,因此在本地windows下使用,先導出dump文件
C:\Users\hz>jmap -dump:format=b,file=test.bin 5152
Dumping heap to C:\Users\hz\test.bin ...
Heap dump file created
而後分析:
C:\Users\hz>jhat test.bin
Reading from test.bin...
Dump file created Wed Dec 30 13:29:19 CST 2015
Snapshot read, resolving...
Resolving 9692 objects...
Chasing references, expect 1 dots.
Eliminating duplicate references.
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
載在瀏覽器中輸入localhost:7000查看結果,以下圖。

 
六、jstack
jstack用於打印出給定的java進程ID或core file或遠程調試服務的Java堆棧信息,若是是在64位機器上,須要指定選項"-J-d64",Windows的jstack使用方式只支持如下的這種方式:
若是java程序崩潰生成core文件,jstack工具能夠用來得到core文件的java stack和native stack的信息,從而能夠輕鬆地知道java程序是如何崩潰和在程序何處發生問題。另外,jstack工具還能夠附屬到正在運行的java程序中,看到當時運行的java程序的java stack和native stack的信息, 若是如今運行的java程序呈現hung的狀態,jstack是很是有用的。 
命令格式 :
jstack [ option ] pid
參數說明:
-F當’jstack [-l] pid’沒有相應的時候強制打印棧信息
-l長列表. 打印關於鎖的附加信息,例如屬於java.util.concurrent的ownable synchronizers列表.
-m打印java和native c/c++框架的全部棧信息.
使用樣例:
[root@tts217 ~]# jstack -l 29984
.....
 
"main" prio=10 tid=0x00007fe648009000 nid=0x7521 runnable [0x00007fe64e753000]
   java.lang.Thread.State: RUNNABLE
 at java.net.PlainSocketImpl.socketAccept(Native Method)
 at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
 at java.net.ServerSocket.implAccept(ServerSocket.java:530)
 at java.net.ServerSocket.accept(ServerSocket.java:498)
 at org.apache.catalina.core.StandardServer.await(StandardServer.java:453)
 at org.apache.catalina.startup.Catalina.await(Catalina.java:777)
 at org.apache.catalina.startup.Catalina.start(Catalina.java:723)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321)
 at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)
 
   Locked ownable synchronizers:
 - None
 
"VM Thread" prio=10 tid=0x00007fe64806a800 nid=0x7522 runnable
 
"VM Periodic Task Thread" prio=10 tid=0x00007fe6480a5800 nid=0x7529 waiting on condition
 
JNI global references: 238
 
2、JDK可視化工具
一、jconsole
JConsole是一個基於JMX的GUI工具,用於鏈接正在運行的JVM,不過此JVM須要使用可管理的模式啓動。若是要把一個應用以可管理的形式啓動,能夠在啓動是設置com.sun.management.jmxremote。
jconsole能夠選擇本地鏈接,來查看本地java程序參數,也能夠鏈接遠程機器來使用,下面鏈接本地看:


a、概述:有關堆內存使用狀況、線程、類加載和CPU使用狀況的綜述。以下圖所示:

 b、內存:堆內存和其餘內存。以下圖所示:

 c、線程:峯值/活動線程,在此頁面能夠查看到各個線程的明細,也能夠進行死鎖檢測。以下圖所示:

 d、類:監控加載和卸載的類,這個須要綜合其餘工具進行具體的分析。
e、VM摘要:有關JVM的明細信息。
f、Mbean:當前Java程序的Mbean的操做。
在jconsole裏主要能夠用來監控內存和線程監控,內存監控至關於jstat,曲線能夠選擇

 能夠手動執行gc。線程監控可用來檢測死鎖。
死鎖代碼以下:
Java代碼   收藏代碼
  1. package jvm;  
  2. /** 
  3.  * 描述: 
  4.  * 
  5.  * @author alaric 2016年1月1日 上午12:43:23 
  6.  */  
  7. public class A implements Runnable {  
  8.  int a, b;  
  9.  public A(int a, int b) {  
  10.   this.a = a;  
  11.   this.b = b;  
  12.  }  
  13.  /* 
  14.   * (non-Javadoc) 
  15.   * 
  16.   * @see java.lang.Runnable#run() 
  17.   */  
  18.  @Override  
  19.  public void run() {  
  20.   // 描述  
  21.   synchronized (Integer.valueOf(a)) {  
  22.    synchronized (Integer.valueOf(b)) {  
  23.     System.out.println(" a + b = " + (a + b));  
  24.    }  
  25.   }  
  26.  }  
  27.  public static void main(String[] args) {  
  28.   for (int i = 0; i < 100; i++) {  
  29.    new Thread(new A(1, 2)).start();  
  30.    new Thread(new A(2, 1)).start();  
  31.   }  
  32.  }  
  33. }  
多運行幾回會出現死鎖,程序會阻塞。而後用線程監控,點擊檢測死鎖,發現Thread-199和Thread-198相互等待釋放Integer.value(1)或者Integer.value(2)。由於在200次的代碼執行中Integer.value()就返回了兩個對象。



 
二、jvisualVM
jvisualVM所謂多合一虛擬機故障處理工具,有強大的插件擴展功能,經過安裝插件擴展支持,jvisualVM能夠作到:
a、顯示虛擬機進程及進程的配置和環境信息(jps,jinfo);
b、監視應用程序CPU、GC、堆、方法區及線程的信息(jstat、jstack);
c、dump及分析堆轉儲快照(jmap、jhat);
d、方法級的程序性能分析,找出調用最多,運行時間最長的方法;
.....其它經過插件能夠作到的;
概述裏面能夠看到虛擬機版本及配置的參數等。
 在監視裏能夠看cpu、堆、線程類的相關數據。能夠執行垃圾回收和dump堆。
 在線程裏能夠看到全部線程,包括運行的、休眠的、等待的、駐留的等,包括運行時間。同時能夠dump線程。

 在抽樣器中能夠監控到每一個方法執行的時間,還能夠對方法過濾。點擊線程cpu時間,能夠看到每一個線程cpu時間。

 VisualGC這裏能夠看到虛擬機運行時每一個區域的容量大小,已佔用的大小,youngGC和fullGC的次數,以及編譯時間、類加載數量和加載時間等。

 
3、總結:
jdk提供的vm故障處理工具都比較實用,經常使用的jps,jstat,jmap,jstack以及可視化工具visualvm,固然根據我的實際實用狀況,可能還選用第三方的工具進行dump分析,如eclipse的MAT(Memory Analyzer Tool)等。靈活實用這些工具,能夠給處理問題帶來很大的便利。
相關文章
相關標籤/搜索