JDK的命令行工具

 Jcmd:綜合工具

jcmd -l  列出當前運行的全部虛擬機html

參數-l表示列出全部java虛擬機,針對每個虛擬機,可使用help命令列出該虛擬機支持的全部命令java

jcmd [pid] help算法

jcmd [pid] VM.uptime   查看虛擬機啓動時間VM.uptimeapache

jcmd [pid] Thread.print  打印線程棧信息Thread.print數組

jcmd 21024 GC.class_histogram  查看系統中類統計信息GC.class_histogram瀏覽器

jcmd [pid] GC.heap_dump [filepath&name]  導出堆信息GC.heap_dump  這個命令功能和 jmap -dump 功能同樣服務器

jcmd [pid] VM.system_properties 獲取系統Properties內容VM.system_propertiesapp

jcmd [pid] VM.flags 獲取啓動參數VM.flagseclipse

jcmd [pid] PerfCounter.print  獲取全部性能相關數據PerfCounter.printjvm

jps:虛擬機進程情況工具

jps(JVM Process Status Tool)能夠列出正在運行的虛擬機進程,並顯示虛擬機執行主類(Main Class,main()函數所在的類)名稱以及這些進程的本地虛擬機惟一ID(Local Virtual Machine Identifier,LVMID)。雖然功能比較單一,但它是使用頻率最高的JDK命令行工具,由於其餘的JDK工具大多須要輸入它查詢到的LVMID來肯定要監控的是哪個虛擬機進程。對於本地虛擬機進程來講,LVMID與操做系統的進程ID(Process Identifier,PID)是一致的,使用Windows的任務管理器或者UNIX的ps命令也能夠查詢到虛擬機進程的LVMID,但若是同時啓動了多個虛擬機進程,沒法根據進程名稱定位時,那就只能依賴jps命令顯示主類的功能才能區分了。

命令格式

 jps [options] [hostid]

option參數

  • -l : 輸出主類全名或jar路徑

  • -q : 只輸出LVMID

  • -m : 輸出JVM啓動時傳遞給main()的參數

  • -v : 輸出JVM啓動時顯示指定的JVM參數

其中[option]、[hostid]參數也能夠不寫。

jinfo

jinfo(JVM Configuration info)這個命令做用是實時查看和調整虛擬機運行參數。 以前的jps -v口令只能查看到顯示指定的參數,若是想要查看未被顯示指定的參數的值就要使用jinfo口令 

命令格式

jinfo [option] [args] LVMID

option參數

  • -flag : 輸出指定args參數的值

  • -flags : 不須要args參數,輸出全部JVM參數的值

  • -sysprops : 輸出系統屬性,等同於System.getProperties()

示例

$ jinfo -flag 11494

-XX:CMSInitiatingOccupancyFraction=80

jstat:虛擬機統計信息監視工具

jstat(JVM statistics Monitoring)是用於監視虛擬機運行時狀態信息的命令,它能夠顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。

命令格式

 jstat [option] LVMID [interval] [count]

參數

  • [option] : 操做參數

  • LVMID : 本地虛擬機進程ID

  • [interval] : 連續輸出的時間間隔

  • [count] : 連續輸出的次數

對於命令格式中的VMID與LVMID須要特別說明一下:

若是是本地虛擬機進程,VMID與LVMID是一致的;

若是是遠程虛擬機進程,那VMID的格式應當是:protocol://lvmid@hostname:port/servername

參數interval和count表明查詢間隔(單位毫秒)和次數,若是省略這兩個參數,說明只查詢一次。

假設須要每250毫秒查詢一次進程2764垃圾收集情況,一共查詢20次,那命令應當是:jstat -gc 2764 250 20

選項option表明着用戶但願查詢的虛擬機信息,主要分爲3類:類裝載、垃圾收集、運行期編譯情況,具體選項及做用請參考表4-3中的描述。

option 參數詳解

-class

監視類裝載、卸載數量、總空間以及耗費的時間

$ jstat -class 11589

 Loaded  Bytes  Unloaded  Bytes     Time   

  7035  14506.3     0     0.0       3.67

  • Loaded : 加載class的數量

  • Bytes : class字節大小

  • Unloaded : 未加載class的數量

  • Bytes : 未加載class的字節大小

  • Time : 加載時間

-compiler

輸出JIT編譯過的方法數量耗時等

$ jstat -compiler 1262

Compiled Failed Invalid   Time   FailedType FailedMethod

2573      1       0    47.60          1               org/apache/catalina/loader/WebappClassLoader findResourceInternal

  • Compiled : 編譯數量

  • Failed : 編譯失敗數量

  • Invalid : 無效數量

  • Time : 編譯耗時

  • FailedType : 失敗類型

  • FailedMethod : 失敗方法的全限定名

-gc

垃圾回收堆的行爲統計,經常使用命令jstat -gc 2764 250 20

S0   S1     E    O    P    YGC  YGCT   FGC  FGCT   GCT

0.00  0.00   6.20  41.42  47.20  16   0.105   3    0.472   0.577

查詢結果代表:這臺服務器的新生代Eden區(E,表示Eden)使用了6.2%的空間,兩個Survivor區(S0、S1,表示Survivor0、Survivor1)裏面都是空的,老年代(O,表示Old)和永久代(P,表示Permanent)則分別使用了41.42%和47.20%的空間。程序運行以來共發生Minor GC(YGC,表示Young GC)16次,總耗時0.105秒,發生Full GC(FGC,表示Full GC)3次,Full GC總耗時(FGCT,表示Full GC Time)爲0.472秒,全部GC總耗時(GCT,表示GC Time)爲0.577秒。

C即Capacity 總容量,U即Used 已使用的容量

  • S0C : survivor0區的總容量

  • S1C : survivor1區的總容量

  • S0U : survivor0區已使用的容量

  • S1C : survivor1區已使用的容量

  • EC : Eden區的總容量

  • EU : Eden區已使用的容量

  • OC : Old區的總容量

  • OU : Old區已使用的容量

  • PC 當前perm的容量 (KB)

  • PU perm的使用 (KB)

  • YGC : 新生代垃圾回收次數

  • YGCT : 新生代垃圾回收時間

  • FGC : 老年代垃圾回收次數

  • FGCT : 老年代垃圾回收時間

  • GCT : 垃圾回收總消耗時間

-gccapacity

同-gc,不過還會輸出Java堆各區域使用到的最大、最小空間

$ jstat -gccapacity 1262

  • NGCMN : 新生代佔用的最小空間

  • NGCMX : 新生代佔用的最大空間

  • OGCMN : 老年代佔用的最小空間

  • OGCMX : 老年代佔用的最大空間

  • OGC:當前年老代的容量 (KB)

  • OC:當前年老代的空間 (KB)

  • PGCMN : perm佔用的最小空間

  • PGCMX : perm佔用的最大空間

-gcutil

同-gc,不過輸出的是已使用空間佔總空間的百分比

-gccause

垃圾收集統計概述(同-gcutil),附加最近兩次垃圾回收事件的緣由

$ jstat -gccause 28920

 S0     S1     E      O      P       YGC     YGCT    FGC    FGCT     GCT       LGCC                 GCC                 

 12.45   0.00  33.85   0.00   4.44      4    0.242     0    0.000    0.242   Allocation Failure   No GC

  • LGCC:最近垃圾回收的緣由

  • GCC:當前垃圾回收的緣由

-gcnew

統計新生代的行爲

$ jstat -gcnew 28920

 S0C      S1C      S0U        S1U  TT  MTT  DSS      EC        EU         YGC     YGCT  

 419392.0 419392.0 52231.8    0.0  6   6    209696.0 3355520.0 1172246.0  4       0.242

  • TT:Tenuring threshold(提高閾值)

  • MTT:最大的tenuring threshold

  • DSS:survivor區域大小 (KB)

-gcnewcapacity

新生代與其相應的內存空間的統計

$ jstat -gcnewcapacity 28920

  • NGC:當前年輕代的容量 (KB)

  • S0CMX:最大的S0空間 (KB)

  • S0C:當前S0空間 (KB)

  • ECMX:最大eden空間 (KB)

  • EC:當前eden空間 (KB)

-gcold

統計舊生代的行爲

 $ jstat -gcold 28920

-gcoldcapacity

統計舊生代的大小和空間

$ jstat -gcoldcapacity 28920

-gcpermcapacity

永生代行爲統計

 $ jstat -gcpermcapacity 28920

-printcompilation

hotspot編譯方法統計

 $ jstat -printcompilation 28920

    Compiled  Size  Type Method

    1291      78     1    java/util/ArrayList indexOf

  • Compiled:被執行的編譯任務的數量

  • Size:方法字節碼的字節數

  • Type:編譯類型

  • Method:編譯方法的類名和方法名。類名使用」/」 代替 「.」 做爲空間分隔符. 方法名是給出類的方法名. 格式是一致於HotSpot – XX:+PrintComplation 選項

jinfo:Java配置信息工具

jinfo(Configuration Info for Java)的做用是實時地查看和調整虛擬機各項參數。使用jps命令的-v參數能夠查看虛擬機啓動時顯式指定的參數列表,但若是想知道未被顯式指定的參數的系統默認值,除了去找資料外,就只能使用jinfo的-flag選項進行查詢了(若是隻限於JDK 1.6或以上版本的話,使用java-XX:+PrintFlagsFinal查看參數默認值也是一個很好的選擇),jinfo還可使用-sysprops選項把虛擬機進程的System.getProperties()的內容打印出來。這個命令在JDK 1.5時期已經隨着Linux版的JDK發佈,當時只提供了信息查詢的功能,JDK 1.6以後,jinfo在Windows和Linux平臺都有提供,而且加入了運行期修改參數的能力,可使用-flag[+|-]name或者-flag name=value修改一部分運行期可寫的虛擬機參數值。JDK 1.6中,jinfo對於Windows平臺功能仍然有較大限制,只提供了最基本的-flag選項。

jinfo命令格式:

jinfo option pid

執行樣例:查詢CMSInitiatingOccupancyFraction參數值。

C:\>jinfo-flag CMSInitiatingOccupancyFraction 1444

-XX:CMSInitiatingOccupancyFraction=85

jmap:Java內存映像工具

jmap(Memory Map for Java)命令用於生成堆轉儲快照(通常稱爲heapdump或dump文件)。

若是不使用jmap命令,要想獲取Java堆轉儲快照,還有一些比較「暴力」的手段:譬如加-XX:+HeapDumpOnOutOfMemoryError參數,可讓虛擬機在OOM異常出現以後自動生成dump文件,經過-XX:+HeapDumpOnCtrlBreak參數則可使用[Ctrl]+[Break]鍵讓虛擬機生成dump文件,又或者在Linux系統下經過Kill-3命令發送進程退出信號「嚇唬」一下虛擬機,也能拿到dump文件。

jmap的做用並不只僅是爲了獲取dump文件,它還能夠查詢finalize執行隊列、Java堆和永久代的詳細信息,如空間使用率、當前用的是哪一種收集器等。和jinfo命令同樣,jmap有很多功能在Windows平臺下都是受限的,除了生成dump文件的-dump選項和用於查看每一個類的實例、空間佔用統計的-histo選項在全部操做系統都提供以外,其他選項都只能在Linux/Solaris下使用。

命令格式

 jmap [option] LVMID

option參數

  • dump : 生成堆轉儲快照,格式爲:-dump:[live, ] format=b,file=<filename>,其中live子參數說明是否只dump出存活的對象。

  • finalizerinfo : 顯示在F-Queue隊列等待Finalizer線程執行finalizer方法的對象

  • heap : 顯示Java堆詳細信息

  • histo : 顯示堆中對象的統計信息,GC使用的算法,heap的配置及wise heap的使用狀況,能夠用此來判斷內存目前的使用狀況以及垃圾回收狀況

  • permstat : to print permanent generation statistics

  • F : 當-dump沒有響應時,強制生成dump快照

示例:

jmap -dump:format=b,file=eclipse.bin 40195 

jmap -dump:live,format=b,file=dump.hprof 28920     dump.hprof這個後綴是爲了後續能夠直接用MAT(Memory Anlysis Tool)打開。

 

jmap -finalizerinfo 28920   打印等待回收對象的信息

  Attaching to process ID 28920, please wait...

  Debugger attached successfully.

  Server compiler detected.

  JVM version is 24.71-b01

  Number of objects pending for finalization: 0

能夠看到當前F-QUEUE隊列中並無等待Finalizer線程執行finalizer方法的對象。

jmap -heap 28920

Attaching to process ID 28920, please wait...
  Debugger attached successfully.
  Server compiler detected.
  JVM version is 24.71-b01  
  using thread-local object allocation.
  Parallel GC with 4 thread(s)//GC 方式  
  Heap Configuration: //堆內存初始化配置
     MinHeapFreeRatio = 0 //對應jvm啓動參數-XX:MinHeapFreeRatio設置JVM堆最小空閒比率(default 40)
     MaxHeapFreeRatio = 100 //對應jvm啓動參數 -XX:MaxHeapFreeRatio設置JVM堆最大空閒比率(default 70)
     MaxHeapSize      = 2082471936 (1986.0MB) //對應jvm啓動參數-XX:MaxHeapSize=設置JVM堆的最大大小
     NewSize          = 1310720 (1.25MB)//對應jvm啓動參數-XX:NewSize=設置JVM堆的‘新生代’的默認大小
     MaxNewSize       = 17592186044415 MB//對應jvm啓動參數-XX:MaxNewSize=設置JVM堆的‘新生代’的最大大小
     OldSize          = 5439488 (5.1875MB)//對應jvm啓動參數-XX:OldSize=<value>:設置JVM堆的‘老生代’的大小
     NewRatio         = 2 //對應jvm啓動參數-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
     SurvivorRatio    = 8 //對應jvm啓動參數-XX:SurvivorRatio=設置年輕代中Eden區與Survivor區的大小比值 
     PermSize         = 21757952 (20.75MB)  //對應jvm啓動參數-XX:PermSize=<value>:設置JVM堆的‘永生代’的初始大小
     MaxPermSize      = 85983232 (82.0MB)//對應jvm啓動參數-XX:MaxPermSize=<value>:設置JVM堆的‘永生代’的最大大小
     G1HeapRegionSize = 0 (0.0MB)  
  Heap Usage://堆內存使用狀況
  PS Young Generation
  Eden Space://Eden區內存分佈
     capacity = 33030144 (31.5MB)//Eden區總容量
     used     = 1524040 (1.4534378051757812MB)  //Eden區已使用
     free     = 31506104 (30.04656219482422MB)  //Eden區剩餘容量
     4.614088270399305% used //Eden區使用比率
  From Space:  //其中一個Survivor區的內存分佈
     capacity = 5242880 (5.0MB)
     used     = 0 (0.0MB)
     free     = 5242880 (5.0MB)
     0.0% used
  To Space:  //另外一個Survivor區的內存分佈
     capacity = 5242880 (5.0MB)
     used     = 0 (0.0MB)
     free     = 5242880 (5.0MB)
     0.0% used
  PS Old Generation //當前的Old區內存分佈
     capacity = 86507520 (82.5MB)
     used     = 0 (0.0MB)
     free     = 86507520 (82.5MB)
     0.0% used
  PS Perm Generation//當前的 「永生代」 內存分佈
     capacity = 22020096 (21.0MB)
     used     = 2496528 (2.3808746337890625MB)
     free     = 19523568 (18.619125366210938MB)
     11.337498256138392% used  
  670 interned Strings occupying 43720 bytes.

jmap -histo:live 28920 | more

打印堆的對象統計,包括對象數、內存大小等等 (由於在dump:live前會進行full gc,若是帶上live則只統計活對象,所以不加live的堆大小要大於加live堆的大小 )

num     #instances         #bytes  class name
----------------------------------------------
   1:         83613       12012248  <constMethodKlass>
   2:         23868       11450280  [B
   3:         83613       10716064  <methodKlass>
   4:         76287       10412128  [C
   5:          8227        9021176  <constantPoolKlass>
   6:          8227        5830256  <instanceKlassKlass>
   7:          7031        5156480  <constantPoolCacheKlass>
   8:         73627        1767048  java.lang.String
   9:          2260        1348848  <methodDataKlass>
  10:          8856         849296  java.lang.Class

xml class name是對象類型,說明以下:

B  byte
C  char
D  double
F  float
I  int
J  long
Z  boolean
[  數組,如[I表示int[]
[L+類名 其餘對象

jhat:虛擬機堆轉儲快照分析工具

jhat(JVM Heap Analysis Tool)命令與jmap搭配使用,來分析jmap生成的堆轉儲快照。jhat內置了一個微型的HTTP/HTML服務器,生成dump文件的分析結果後,能夠在瀏覽器中查看。

不過實事求是地說,在實際工做中,除非手上真的沒有別的工具可用,不然通常都不會去直接使用jhat命令來分析dump文件,主要緣由有二:一是通常不會在部署應用程序的服務器上直接分析dump文件,即便能夠這樣作,也會盡可能將dump文件複製到其餘機器。二是用於分析的機器通常也是服務器,因爲加載dump快照文件須要比生成dump更大的內存,因此通常在64位JDK、大內存的服務器上進行分析,由於分析工做是一個耗時並且消耗硬件資源的過程,既然都要在其餘機器進行,就沒有必要受到命令行工具的限制了;另外一個緣由是jhat的分析功能相對來講比較簡陋,VisualVM,以及專業用於分析dump文件的Eclipse Memory Analyzer、IBM HeapAnalyzer等工具,都能實現比jhat更強大更專業的分析功能。

命令格式

 jhat [option] [dumpfile]

參數

  • -stack false|true 關閉對象分配調用棧跟蹤(tracking object allocation call stack)。 若是分配位置信息在堆轉儲中不可用. 則必須將此標誌設置爲 false. 默認值爲 true.>

  • -refs false|true 關閉對象引用跟蹤(tracking of references to objects)。 默認值爲 true. 默認狀況下, 返回的指針是指向其餘特定對象的對象,如反向連接或輸入引用(referrers or incoming references), 會統計/計算堆中的全部對象。>

  • -port port-number 設置 jhat HTTP server 的端口號. 默認值 7000.> 

  • -exclude exclude-file 指定對象查詢時須要排除的數據成員列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 若是文件列列出了 java.lang.String.value , 那麼當從某個特定對象 Object o 計算可達的對象列表時, 引用路徑涉及 java.lang.String.value 的都會被排除。>

  • -baseline exclude-file 指定一個基準堆轉儲(baseline heap dump)。 在兩個 heap dumps 中有相同 object ID 的對象會被標記爲不是新的(marked as not being new). 其餘對象被標記爲新的(new). 在比較兩個不一樣的堆轉儲時頗有用.>

  • -debug int 設置 debug 級別. 0 表示不輸出調試信息。 值越大則表示輸出更詳細的 debug 信息.>

  • -version 啓動後只顯示版本信息就退出>

  • -J< flag > 由於 jhat 命令實際上會啓動一個JVM來執行, 經過 -J 能夠在啓動JVM時傳入一些啓動參數. 例如, -J-Xmx512m 則指定運行 jhat 的Java虛擬機使用的最大堆內存爲 512 MB. 若是須要使用多個JVM啓動參數,則傳入多個 -Jxxxxxx.

➜  ~ jhat eclipse.bin 

Reading from eclipse.bin...

Dump file created Mon Oct 31 19:32:57 CST 2016

Snapshot read, resolving...

Resolving 185857 objects...

Chasing references, expect 37 dots.....................................

Eliminating duplicate references.....................................

Snapshot resolved.

Started HTTP server on port 7000

Server is ready.

屏幕顯示「Server is ready.」的提示後,用戶在瀏覽器中鍵入http://localhost:7000/就能夠看到分析結果.

分析結果默認是以包爲單位進行分組顯示,分析內存泄漏問題主要會使用到其中的「Heap Histogram」(與jmap -histo功能同樣)與OQL頁籤的功能,前者能夠找到內存中總容量最大的對象,後者是標準的對象查詢語言,使用相似SQL的語法對內存中的對象進行查詢統計.

jstack:Java堆棧跟蹤工具

jstack(Stack Trace for Java)命令用於生成虛擬機當前時刻的線程快照(通常稱爲threaddump或者javacore文件)。線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的緣由,如線程間死鎖、死循環、請求外部資源致使的長時間等待等都是致使線程長時間停頓的常見緣由。線程出現停頓的時候經過jstack來查看各個線程的調用堆棧,就能夠知道沒有響應的線程到底在後臺作些什麼事情,或者等待着什麼資源。

命令格式

 jstack [option] LVMID

option參數

  • -F : 當正常輸出請求不被響應時,強制輸出線程堆棧

  • -l : 除堆棧外,顯示關於鎖的附加信息

  • -m : 若是調用到本地方法的話,能夠顯示C/C++的堆棧

➜  ~ jstack -l 40195

在JDK 1.5中,java.lang.Thread類新增了一個getAllStackTraces()方法用於獲取虛擬機中全部線程的StackTraceElement對象。使用這個方法能夠經過簡單的幾行代碼就完成jstack的大部分功能,在實際項目中不妨調用這個方法作個管理員頁面,能夠隨時使用瀏覽器來查看線程堆棧。

<%@page import="java.util.Map"%>
<html>
<head>
<title>服務器線程信息</title>
</head>
<body>
<pre>
<%
for(Map.Entry<Thread,StackTraceElement[]>stackTrace:Thread.getAllStackTraces().entrySet()){
  Thread thread=(Thread)stackTrace.getKey();
  StackTraceElement[]stack=(StackTraceElement[])stackTrace.getValue();
  if(thread.equals(Thread.currentThread())){
    continue;
  }
  out.print("\n線程:"+thread.getName()+"\n");
  for(StackTraceElement element:stack){
    out.print("\t"+element+"\n");
  }
}
%>
</pre>
</body>
</html>
相關文章
相關標籤/搜索