JDK 命令行工具
jps
列出正在運行的虛擬機進程,並顯示虛擬機執行(main()函數所在主類)名稱 以及 這些進程的本地虛擬機唯一ID。
命令格式爲。
jps [ options ] [ hostid ]
其中選項option代表用戶希望查詢的虛擬機信息,主要分爲三類:類加載,垃圾收集,運行期編譯狀況,常用的option選項如下
如下圖所示,210636是本地虛擬機唯一ID。
(1)jps -l 輸出主類的全名
(2)jps -v 輸出虛擬機進程啓動時JVM參數
(3)jps -m 輸出傳遞給Java進程main函數的參數
jstat
監視虛擬機各種運行狀態信息。它可以顯示本地或遠程虛擬機進程中的類加載,內存,垃圾收集,即使編譯等運行時數據。
命令格式如下。參數interval和count代表查詢間隔和次數,若省略則只查詢一次,比如 jstat -gc 2764 250 20 意思爲每250毫秒查詢一次進程2764垃圾收集狀況,一共查詢20次
jstat [ option vmid [interval[s|ms] [count]] ]
如果是本地虛擬機進程,vmid與lvmid是一致的;若是遠程虛擬機進程,則vmid的格式應爲:
[protocol:][//]lvmid[@hostname[:port]/servername]
測試:監視一臺服務器的內存狀況:
jstat -gcutil 2764
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使用了6.2%的空間,2個Survivor區(S0,S1)裏面爲空,老年代Old和永久代Permanent分別使用了41/42%和47.20%的空間。程序運行以來共發生Minor GC(YGC,表示Young GC)16次,總耗時0.105秒;發生Full GC(FGC,表示Full GC)3次,總耗時(FGCT,表示Full GC Time)爲0.472秒;所有GC總耗時(GCT,表示GC Time)爲0.577秒。
jinfo
實時查看和調增虛擬機各項參數。前面提到的jps命令的-v參數可以查看虛擬機啓動時顯示指定的參數列表,但如果想知道未被顯示指定的參數的系統默認值,可以使用jinfo的 -flag進行查詢。
測試:如果我們希望查看虛擬機是否使用了某個收集器,如下所示。結果是+表示使用的是CMS收集器;若冒號後面跟的是-,則表示不是使用給定的收集器
jinfo -flag UseConcMarkSweepGC 210636
-XX:+UseConcMarkSweepGC
測試:查詢CMSInitiatingOccupancyFraction參數值
jinfo -flag CMSInitiatingOccupancyFraction 210636
-XX:CMSInitiatingOccupancyFraction=-1
jmap
生成堆存儲快照。同時也可以查詢finalize執行隊列,Java堆和方法區的信息(如空間使用率,當前使用的是哪種收集器等)。
測試:在F盤生成a.bin堆存儲快照(注:須在管理員模式下cmd)。可通過Visual 等工具分析文件
jmap -dump:format=b,file=F:\a.bin 210636
Dumping heap to F:\a.bin ...
Heap dump file created
jhat
與jmap搭配使用,用於分析其生成的堆轉儲快照。jhat內置一個微型的HTTP/Web服務器,使用戶可以在瀏覽器查看分析結果。
測試:在http://localhost:7000/中查看前面生成的堆存儲快照
jhat f:\a.bin
...省略前面輸出
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
jstack
生成虛擬機當前時刻的線程快照(當前虛擬機內每一條線程正在執行的方法堆棧的集合)。生成線程快照的目的是定位線程出現長時間聽到的原因,如線程間死鎖,死循環等。
測試:下面是一段死鎖代碼
public class JavaVM {
private static Object resource1 = new Object();
private static Object resource2 = new Object();
public static void main(String[] args) throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}
}, "線程 1").start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}
}, "線程 2").start();
}
}
通過監視器jstack命令分析:
jstack 148688
Found one Java-level deadlock:
=============================
"線程 2":
waiting to lock monitor 0x0000000002bfaf98 (object 0x000000076bc2a1b8, a java.lang.Object),
which is held by "線程 1"
"線程 1":
waiting to lock monitor 0x0000000002bf8708 (object 0x000000076bc2a1c8, a java.lang.Object),
which is held by "線程 2"Java stack information for the threads listed above:
===================================================
"??程 2":
at JavaVM$2.run(JavaVM.java:47)
- waiting to lock <0x000000076bc2a1b8> (a java.lang.Object)
- locked <0x000000076bc2a1c8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"線程 1":
at JavaVM$1.run(JavaVM.java:29)
- waiting to lock <0x000000076bc2a1c8> (a java.lang.Object)
- locked <0x000000076bc2a1b8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)Found 1 deadlock.
JDK 可視化分析工具
JConsole:Java監視與管理控制檯
它的主要功能是通過JMX的MBean對系統進行信息收集和參數動態調整。
通過JDK/bin目錄下的jconsole.exe啓動JConsole後,會自動搜索出本機運行的所有虛擬機進程。它可以對遠程虛擬機進行監控
內存監控
jconsole可以顯示當前內存的詳細信息,包括堆內存,非堆內存,新生代,survior區等使用情況。
點擊 “執行CG”按鈕可以強制執行一個Full GC
線程監控
同樣,jconsole可以做一次類似可視化的jstack命令的線程監控
VisualVM:多合-故障處理工具
它是一個運行監視和故障處理的程序,可以做到:
- 顯示虛擬機進程以及進程的配置、環境信息(jps、jinfo)。
- 監視應用程序的 CPU、GC、堆、方法區以及線程的信息(jstat、jstack)。
- dump 以及分析堆轉儲快照(jmap、jhat)。
- 方法級的程序運行性能分析,找到被調用最多、運行時間最長的方法。