跟著練、包會(JVM調優工具)

welchang發表於2021-09-09

調優命令可以在 檢視對應JDK版本文件,下文所有的命令都是基於JDK8的。

圖片描述


找到JVM工具目錄

[root@localhost ~]# find / -name javac
/home/java/jdk1.8.0_181/bin/javac
或者
[root@localhost ~]# which javac
/home/java/jdk1.8.0_181/bin/javac

find搜尋預設為當前路徑,可以指定路徑,-name是用名字進行搜尋,可以正規表示式,which只會在PATH路徑下搜尋。

列出工具

[root@localhost bin]# lsappletviewer  jar        javadoc         javapackager  jconsole  jhat   jmc         jsadebugd  jvisualvm     pack200     rmiregistry  tnameserv  xjcControlPanel  jarsigner  javafxpackager  java-rmi.cgi  jcontrol  jinfo  jmc.ini     jstack     keytool       policytool  schemagen    unpack200extcheck      java       javah           javaws        jdb       jjs    jps         jstat      native2ascii  rmic        serialver    wsgenidlj          javac      javap           jcmd          jdeps     jmap   jrunscript  jstatd     orbd          rmid        servertool   wsimport

/home/java/jdk1.8.0_181/bin目錄下面的命令比較多,我們根本不需要全部瞭解,下面選擇JVM相關的進行講解。

找出JAVA程式(jps)

列出當前系統JAVA程式

[root@localhost bin]# jps -lvm3299 sun.tools.jps.Jps -lvm -Dapplication.home=/home/java/jdk1.8.0_181 -Xms8m999 org.apache.zookeeper.server.quorum.QuorumPeerMain /home/zookeeper/zookeeper-3.4.13/bin/../conf/zoo.cfg -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false1255 spring4-0.0.1-SNAPSHOT.jar1021 zkui-2.0-SNAPSHOT-jar-with-dependencies.jar

-l 輸出應用程式主類完整package名稱或jar完整名稱.
-v 列出啟動程式指定的jvm引數
-m 輸出主函式傳入的引數.

監控JVM(jstat)

JVM實時監控的工具,包括類載入資訊、及時編譯、GC等

jstat -options
-class   //列舉類裝載資訊
-compiler  //列舉及時編譯資訊
-gc   //列舉jvm記憶體使用和gc資訊
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation

引數太多記不住,只需要重點關注2個:-gc以及-gcutil。

需要注意,命令都是基於當前時間的統計資訊,但是可以使用引數來控制列印的次數與間隔:例如jstat -gcutil 21891 1000 7 將會間隔1000毫秒列印一次,一共列印7次

引數 -gc

列出jvm記憶體堆和GC資訊

[root@localhost bin]# jstat -gc 999
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
512.0  512.0   20.2   0.0    4416.0   4145.3   10944.0     2894.0   10496.0 10272.1 1280.0 1180.6     58    0.246   0      0.000    0.246

c表示capacity(容量:kb),例如S0c表示survivor space 0 的容量;
u表示utilization(已使用:kb),例如OU表示老年代使用
CCSC這個在jdk8中才有的,在64bit的JVM中,用來儲存壓縮的原始指標的空間;
YGC 、YGCT 、FGC  、FGCT 、GCT這幾個是GC統計,字面意思應該比較清楚。

引數 -gcutil

列出JVM統計資訊,不過相對於-gc引數更清爽,而記憶體使用率卻以百分比形式給出

[root@localhost simple]# jstat -gcutil 1021
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.08   0.00  20.35  78.59  98.57  95.44     34    0.850     4    0.124    0.974

例如:O 表示老年代記憶體使用率百分比。

記憶體詳情(jmap)

將JVM記憶體資訊轉儲到指定檔案,例如:jmap -dump:format=b,file=heap.bin 999

[root@localhost simple]# jmap -dump:format=b,file=heap.bin  999
Dumping heap to /home/java/simple/heap.bin ...
Heap dump file created
[root@localhost simple]# ls
heap.bin
[root@localhost simple]#

-dump引數解釋:

live         可選引數,表示轉儲活躍的物件
format=b     二進位制格式
file=<file>  指定檔名稱

堆分析(jhat)

jhat 命令將解析java堆dump檔案,並啟動一個web服務展示分析結果。
jhat heap.bin,命令將會啟動服務,透過瀏覽器可以進行訪問:,可以看到物件的統計資訊,包括:物件例項數量,物件佔用記憶體空間多少等等。
當然我們也可以把dump檔案下載到本地,用jvisualvm工具進行裝載,然後檢視,展示效果更好。

執行緒軌跡(jstack)

jstack pid列印Java程式中執行緒的軌跡,包括:執行緒id、執行緒棧、狀態(是否鎖等待)等。

"ProcessThread(sid:0 cport:2181):" #13 prio=5 os_prio=0 tid=0x00007f0c7c2a2800 nid=0x3fb waiting on condition [0x00007f0c6cffe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f5ff2e58> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.zookeeper.server.PrepRequestProcessor.run(PrepRequestProcessor.java:123)

cpu使用率過高排查

top檢視當前程式佔用cpu情況:

[root@localhost simple]# top
top - 01:24:41 up  7:03,  3 users,  load average: 0.00, 0.01, 0.05
Tasks:  99 total,   2 running,  97 sleeping,   0 stopped,   0 zombie%Cpu(s):  0.0 us,  0.7 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem :   997948 total,   163352 free,   514020 used,   320576 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.   272652 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                
   875 root      20   0  214424   5000   3192 S  0.3  0.5   0:02.48 rsyslogd                                                                                               
  1021 root      20   0 2322672 211788  14072 S  0.3 21.2   1:05.56 java

然後找到程式中執行緒使用cpu情況

[root@localhost simple]# top -H -p 999top - 01:31:06 up  7:09,  3 users,  load average: 0.00, 0.01, 0.05Threads:  16 total,   0 running,  16 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   997948 total,   163412 free,   513952 used,   320584 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.   272720 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                             
   999 root      20   0 2253296  69380  13100 S  0.0  7.0   0:00.05 java                                                                                                
  1002 root      20   0 2253296  69380  13100 S  0.0  7.0   0:01.38 java

找到對應的執行緒,轉換執行緒號為16進位制:printf %x 1022
然後在jstack列印的執行緒資訊中,找到對應的執行緒執行的程式碼,最後深度程式碼codereview。



作者:關捷
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4830/viewspace-2818528/,如需轉載,請註明出處,否則將追究法律責任。

相關文章