天天看點

深入了解JVM - JVM常用指令

  • ​jps​

    ​(JVM Process Status Tool):顯示指定系統内所有的HotSpot虛拟機程序
  • ​jstat​

    ​(JVM Statistics Monitoring Tool):使用者收集HotSpot虛拟機各方面的運作資料
  • ​jinfo​

    ​​(Configuration Info for Java):實時檢視和調整虛拟機各項參數,在JDK9中內建到了​

    ​jhsdb​

  • ​jmap​

    ​​(Memory Map for java):生成虛拟機的記憶體轉儲快照,在JDK9中內建到了​

    ​jhsdb​

  • ​jhat​

    ​​(JVM Heap Dump Browser):使用者分析heapdump檔案,它會建立一個HTTP/HTML伺服器,讓使用者可以在浏覽器上檢視分析結果,在JDK9中內建到了​

    ​jhsdb​

  • ​jstack​

    ​​(Stack Trace for Java):生成虛拟機目前時刻的線程快照,在JDK9中內建到了​

    ​jhsdb​

  • ​jhsdb​

    ​(Java HotSport Debugger):程序調試器,在JDK9引入

如果執行指令報錯,大部分是因為使用者問題,我們可以通過 ​

​top​

​​指令,或者 ​

​ps -ef|gerp java​

​​指令檢視到程序使用者,然後通過​

​sudo -u appuser jps​

​方式來執行指令:

深入了解JVM - JVM常用指令

示例:

[lhadmin@BJTVMYTEAM-2 tmp]$ sudo -u appuser jmap -dump:file=/tem/heap.bin 22014
Dumping heap to /tem/heap.bin ...
No such file or directory
[lhadmin@BJTVMYTEAM-2 tmp]$ sudo -u appuser java -jar arthas-boot.jar 
[INFO] arthas-boot version: 3.5.1      

jps

列出目前機器上正在運作的虛拟機程序,jps指令格式:

jps [option] [hostid]      

-p: 僅僅顯示VM 标示,不顯示jar,class, main參數等資訊.

-m: 輸出主函數傳入的參數. 下的hello 就是在執行程式時從指令行輸入的參數

-l: 輸出應用程式主類完整package名稱或jar完整名稱.

-v: 列出jvm參數

執行樣例:

C:\Users\yuhao.wang3>jps -l
11824 sun.tools.jps.Jps
9860 org.jetbrains.idea.maven.server.RemoteMavenServer
7960      

ps

檢視java程序​

​ps -ef|grep java​

[1014154@etc-credit-card-devga-75cd56548c-kf4t5 ~]$ ps -ef|grep java
ymmapp      295    146 15 11:23 ?        00:01:45 /usr/local/jdk1.8.0_131/bin/java -Djava.util.logging.config.file=/home/ymmapp/etc-credit-card/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xms512m -Xmx512m -XX:NewSize=256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:MaxTenuringThreshold=15 -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass -XX:+UseParNewGC -XX:CMSFullGCsBeforeCompaction=100 -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -Dhealthcheck.flow.enter.control=true -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=40000 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/ymmapp/applogs/system/gc_202004101123.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/applogs/system/ -XX:ErrorFile=/data/applogs/system/java_error.log -Djava.endorsed.dirs=/home/ymmapp/etc-credit-card/endorsed -classpath /home/ymmapp/etc-credit-card/bin/bootstrap.jar:/home/ymmapp/etc-credit-card/bin/tomcat-juli.jar -Dcatalina.base=/home/ymmapp/etc-credit-card -Dcatalina.home=/home/ymmapp/etc-credit-card -Djava.io.tmpdir=/home/ymmapp/etc-credit-card/temp org.apache.catalina.startup.Bootstrap start
1014154   25875  24404  0 11:34 pts/0    00:00:00 grep --color=auto java      

jstat

是用于監視虛拟機各種運作狀态資訊的指令行工具。它可以顯示本地或者遠端虛拟機程序中的類裝載、記憶體、垃圾收集、JIT編譯等運作資料,在沒有GUI圖形界面,隻提供了純文字控制台環境的伺服器上,它将是運作期定位虛拟機性能問題的首選工具。

jstat [ option pid [interval[s|ms] [count]] ]      

假設需要每250毫秒查詢一次程序9860垃圾收集狀況,一共查詢5次,那指令應當是:

C:\Users\yuhao.wang3>jstat -gc 9860 250 5
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
10752.0 10752.0  0.0    0.0   64512.0   867.6    76800.0     8207.2   23808.0 22909.2 3072.0 2769.6      6    0.049   4      0.209    0.258
10752.0 10752.0  0.0    0.0   64512.0   867.6    76800.0     8207.2   23808.0 22909.2 3072.0 2769.6      6    0.049   4      0.209    0.258
10752.0 10752.0  0.0    0.0   64512.0   867.6    76800.0     8207.2   23808.0 22909.2 3072.0 2769.6      6    0.049   4      0.209    0.258
10752.0 10752.0  0.0    0.0   64512.0   867.6    76800.0     8207.2   23808.0 22909.2 3072.0 2769.6      6    0.049   4      0.209    0.258
10752.0 10752.0  0.0    0.0   64512.0   867.6    76800.0     8207.2   23808.0 22909.2 3072.0 2769.6      6    0.049   4      0.209    0.258      
  • S0C:表示S0區域總大小
  • S0U:表示S0區域已使用大小

jinfo

檢視和修改虛拟機的參數,指令格式:

jinfo [option] pid      

jinfo –sysprops 可以檢視由System.getProperties()取得的參數

jinfo –flag 未被顯式指定的參數的系統預設值

jinfo –flags(注意s)顯示虛拟機的參數

jinfo –flag +[參數] 可以增加參數,但是僅限于由java -XX:+PrintFlagsFinal –version查詢出來且

執行示例:

C:\Users\yuhao.wang3>jinfo -flags 9860
Attaching to process ID 9860, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b15
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=264241152 -XX:MaxHeapSize=805306368 -XX:MaxNewSize=268435456 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88080384 -XX:OldSize=176160768 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -Djava.awt.headless=true -Didea.version==2018.3.2 -Xmx768m -Didea.maven.embedder.version=3.3.9 -Dfile.encoding=GBK      

jmap

用于生成堆轉儲快照(一般稱為heapdump或dump檔案)。jmap的作用并不僅僅是為了擷取dump檔案,它還可以查詢finalize執行隊列、Java堆和永久代的詳細資訊,如空間使用率、目前用的是哪種收集器等。和jinfo指令一樣,jmap有不少功能在Windows平台下都是受限的,除了生成dump檔案的-dump選項和用于檢視每個類的執行個體、空間占用統計的-histo選項在所有作業系統都提供之外,其餘選項都隻能在Linux/Solaris下使用,指令格式:

jmp [option] pid      

生成堆的轉存檔案:

C:\Users\yuhao.wang3>jmap -dump:live,format=b,file=heap.bin 9860
Dumping heap to C:\Users\yuhao.wang3\heap.bin ...
Heap dump file created      

jhat

虛拟機堆轉儲快照分析工具

分析剛剛生成的檔案:

C:\Users\yuhao.wang3>jhat C:\Users\yuhao.wang3\heap.bin
Reading from C:\Users\yuhao.wang3\heap.bin...
Dump file created Tue Jan 14 17:59:13 CST 2020
Snapshot read, resolving...
Resolving 151163 objects...
Chasing references, expect 30 dots..............................
Eliminating duplicate references..............................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.      

螢幕顯示“Server is ready.”的提示後,使用者在浏覽器中輸入http://localhost:7000/可以看到分析結果,拖到最下面,主要看"HeapHistogram"。

jstack

jstack(Stack Trace for Java)指令用于生成虛拟機目前時刻的線程快照。線程快照就是目前虛拟機内每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導緻的長時間等待等都是導緻線程長時間停頓的常見原因,指令格式:

jstack [option] pid      

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

-l:除堆棧外,顯示關于鎖的附加資訊

-m:如果調用到本地方法的話,可以顯示C/C++的堆棧

查詢死循環示例:

public class JstackDeadWhileTest {

    public static void main(String[] args) {
        int i = 1;
        while (++i > 0) {
            System.out.println(i);
        }
    }
}      
C:\Users\yuhao.wang3>jps -l
18244 com.xiaolyuh.JstackDeadWhileTest
5444 org.jetbrains.jps.cmdline.Launcher
7960
10252 sun.tools.jps.Jps
17324 org.jetbrains.kotlin.daemon.KotlinCompileDaemon

C:\Users\yuhao.wang3>jstack -F 18244
Attaching to process ID 18244, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b15
Deadlock Detection:

No deadlocks found.

Thread 14: (state = BLOCKED)


Thread 13: (state = BLOCKED)


Thread 12: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove(long) @bci=59, line=143 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove() @bci=2, line=164 (Interpreted frame)
 - java.lang.ref.Finalizer$FinalizerThread.run() @bci=36, line=209 (Interpreted frame)


Thread 11: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.Object.wait() @bci=2, line=502 (Interpreted frame)
 - java.lang.ref.Reference.tryHandlePending(boolean) @bci=54, line=191 (Interpreted frame)
 - java.lang.ref.Reference$ReferenceHandler.run() @bci=1, line=153 (Interpreted frame)


Thread 5: (state = IN_NATIVE)
 - java.io.FileOutputStream.writeBytes(byte[], int, int, boolean) @bci=0 (Compiled frame; information may be imprecise)
 - java.io.FileOutputStream.write(byte[], int, int) @bci=8, line=326 (Compiled frame)
 - java.io.BufferedOutputStream.flushBuffer() @bci=20, line=82 (Compiled frame)
 - java.io.BufferedOutputStream.flush() @bci=1, line=140 (Compiled frame)
 - java.io.PrintStream.write(byte[], int, int) @bci=30, line=482 (Compiled frame)
 - sun.nio.cs.StreamEncoder.writeBytes() @bci=120, line=221 (Compiled frame)
 - sun.nio.cs.StreamEncoder.implFlushBuffer() @bci=11, line=291 (Compiled frame)
 - sun.nio.cs.StreamEncoder.flushBuffer() @bci=15, line=104 (Compiled frame)
 - java.io.OutputStreamWriter.flushBuffer() @bci=4, line=185 (Compiled frame)
 - java.io.PrintStream.write(java.lang.String) @bci=27, line=527 (Compiled frame)
 - java.io.PrintStream.print(int) @bci=5, line=597 (Compiled frame)
 - java.io.PrintStream.println(int) @bci=6, line=736 (Compiled frame)
 - com.xiaolyuh.JstackDeadWhileTest.main(java.lang.String[]) @bci=13, line=14 (Compiled frame)      
在代碼中可以用java.lang.Thread類的getAllStackTraces()方法用于擷取虛拟機中所有線程的StackTraceElement對象。使用這個方法可以通過簡單的幾行代碼就完成jstack的大部分功能,在實際項目中不妨調用這個方法做個管理者頁面,可以随時使用浏覽器來檢視線程堆棧。

性能監控和故障處理工具

深入了解JVM - JVM常用指令

VisualVM:多合-故障處理工具

直接運作指令​

​jvisualvm​

​就可以打開VisualVM工具了。

插件安裝

先去這個位址找到對應版本的插件位址(https://xxx/updates.xml.gz):

​​​https://visualvm.github.io/pluginscenters.html​​

繼續閱讀