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(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(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(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(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(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(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(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>