昨天推送了一本jvm相關的書籍 【JVM Troubleshooting Guide】書籍推薦及下載,個別小夥伴反饋說關於jvm看了不少資料,有些印象,但是不知道如何使用那些命令。
就著這個前提,簡單演示一下jvm一些命令的使用。(溫馨提示,由於jvm命令返回的字符串偏長一些,手機上效果差一些,建議在電腦上看)
首先,先準備一段代碼,直接運行一個java程序也可以,比如:
@Slf4j
public class SearchBusiestCPU {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread() {
public void run() {
try {
Thread.sleep(100000);
} catch (Exception e) {
log.error("exception", e);
}
}
}.start();
}
Thread t = new Thread() {
public void run() {
int i = 0;
while (true) {
i = (i++) / 100;
}
}
};
t.setName("Buiest thread");
t.start();
}
}
1)jps
JVM Process Status Tool,顯示指定系統內所有的HotSpot虛擬機進程
~ ᐅ jps
87344 Jps
86199 Launcher
86200 SearchBusiestCPU
34413
從結果可以看出當前的java進程為 86200
2)jstack
用於生成java虛擬機當前時刻的線程快照。線程快照是當前java虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等。 線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在後臺做什麼事情,或者等待什麼資源。如果現在運行的java程序呈現hung的狀態,jstack是非常有用的。
一個比較好的實踐是間隔幾秒執行兩次,對比著來看一些線程的狀態
~ ᐅ jstack -l 86200
2018-06-27 09:06:27
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.92-b14 mixed mode):
"Attach Listener" #22 daemon prio=9 os_prio=31 tid=0x00007f93b9865000 nid=0xd07 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"DestroyJavaVM" #21 prio=5 os_prio=31 tid=0x00007f93b996b800 nid=0x1803 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Buiest thread" #20 prio=5 os_prio=31 tid=0x00007f93b8138800 nid=0xa203 runnable [0x0000700004903000]
java.lang.Thread.State: RUNNABLE
at com.mmall.practice.example.jvm.SearchBusiestCPU$2.run(SearchBusiestCPU.java:176)
Locked ownable synchronizers:
- None
。。。省略一部分細節。。。
"VM Thread" os_prio=31 tid=0x00007f93b9842000 nid=0x2d03 runnable
"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007f93b980d000 nid=0x1d07 runnable
"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007f93b980d800 nid=0x1f03 runnable
"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007f93b980e800 nid=0x2a03 runnable
"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007f93b980f000 nid=0x5403 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007f93b8aea000 nid=0x3b03 waiting on condition
JNI global references: 62
3)jstat
JVM statistics Monitoring,用於監視虛擬機運行時狀態信息的命令,它可以顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。
~ ᐅ jstat -gcutil 86200 1000 5
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 2.00 1.79 88.96 81.47 2 0.005 2 0.014 0.019
0.00 0.00 2.00 1.79 88.96 81.47 2 0.005 2 0.014 0.019
0.00 0.00 2.00 1.79 88.96 81.47 2 0.005 2 0.014 0.019
0.00 0.00 2.00 1.79 88.96 81.47 2 0.005 2 0.014 0.019
0.00 0.00 2.00 1.79 88.96 81.47 2 0.005 2 0.014 0.019
4)jmap
JVM Memory Map,用於生成heap dump文件,可以使用-XX:+HeapDumpOnOutOfMemoryError參數來讓虛擬機出現OOM的時候·自動生成dump文件。
jmap不僅能生成dump文件,還可以查詢finalize執行隊列、Java堆和永久代的詳細信息,如當前使用率、當前使用的是哪種收集器等。
~ ᐅ jmap -histo:live 86200
num #instances #bytes class name
-
1: 4820 477952 [C
2: 558 134984 [B
3: 4802 115248 java.lang.String
4: 873 100024 java.lang.Class
5: 865 54864 [Ljava.lang.Object;
6: 1478 47296 java.util.HashMap$Node
7: 464 30904 [I
8: 343 21952 java.net.URL
9: 57 15808 [Ljava.util.HashMap$Node;
10: 486 15552 java.util.concurrent.ConcurrentHashMap$Node
11: 128 12288 java.util.jar.JarFile$JarFileEntry
。。。省略。。。
345: 1 16 sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total 19993 1227944
dump出文件:
~ ᐅ jmap -dump:format=b,file=/tmp/dump0627.dat 86200
Dumping heap to /private/tmp/dump0627.dat ...
Heap dump file created
4) jhat
JVM Heap Analysis Tool,與jmap搭配使用,用來分析jmap生成的dump,jhat內置了一個微型的HTTP/HTML伺服器,生成dump的分析結果後,可以在瀏覽器中查看。
在此要注意,一般不會直接在伺服器上進行分析,因為jhat是一個耗時並且耗費硬體資源的過程,一般把伺服器生成的dump文件複製到本地或其他機器上進行分析。當然,jmap dump的文件也可以使用MA等工具來分析,本文重點介紹一下jvm一些命令的使用,這裡就不做擴展了。
~ ᐅ jhat -port 9998 /tmp/dump0627.dat
Reading from /tmp/dump0627.dat...
Dump file created Wed Jun 27 09:09:10 CST 2018
Snapshot read, resolving...
Resolving 19995 objects...
Chasing references, expect 3 dots...
Eliminating duplicate references...
Snapshot resolved.
Started HTTP server on port 9998
Server is ready.
之後可訪問 http://localhost:9998/ 查看:
5)jinfo
JVM Configuration info,這個命令作用是實時查看和調整虛擬機運行參數。
~ ᐅ jinfo -flags 86200
Attaching to process ID 86200, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.92-b14
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:OldSize=179306496 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line: -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=53964:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
以上演示了常用jvm命令的使用,限於文章篇幅,並沒有對每個命令進行詳細的參數介紹和結果解讀,這些內容留到後面的文章再繼續深入。著急的話,可以先去網上自己搜索看一下,應該可以查到很多不錯的整理。
其他文章推薦
面試中並發類問題的準備和學習
自定義註解完成資料庫切庫
多個數據源輕鬆支持
改造電商交易後臺權限管理過程
數據權限通用設計方案
簡談從零開始搭建一套業務相關監控報警系統
Java項目中使用log記錄日誌的一些總結
Redis在股票分時K線圖計算的實踐
並發之Fork/Join框架使用及注意點
Java並發編程與高並發解決方案:
https://coding.imooc.com/class/195.html
Java開發企業級權限管理系統:
https://coding.imooc.com/class/149.html
歡迎大家多多留言,說出你想看的文章或者希望學習的技術棧~
別忘了關注我哦~