(轉)JVM調優常用命令(jstat、jmap、jstack)

zzz紫川發表於2019-01-05

 

原文https://www.cnblogs.com/ityouknow/p/5714703.html

一、jstat

  jstat(JVM statistics Monitoring)是用於監視虛擬機器執行時狀態資訊的命令,它可以顯示出虛擬機器程式中的類裝載、記憶體、垃圾收集、JIT編譯等執行資料。

命令格式

jstat [option] LVMID [interval] [count]

[option] : 操作引數
LVMID : 本地虛擬機器程式ID
[interval] : 連續輸出的時間間隔
[count] : 連續輸出的次數

option 引數總覽

OptionDisplays…
class class loader的行為統計。Statistics on the behavior of the class loader.
compiler HotSpt JIT編譯器行為統計。Statistics of the behavior of the HotSpot Just-in-Time compiler.
gc 垃圾回收堆的行為統計。Statistics of the behavior of the garbage collected heap.
gccapacity 各個垃圾回收代容量(young,old,perm)和他們相應的空間統計。Statistics of the capacities of the generations and their corresponding spaces.
gcutil 垃圾回收統計概述。Summary of garbage collection statistics.
gccause 垃圾收集統計概述(同-gcutil),附加最近兩次垃圾回收事件的原因。Summary of garbage collection statistics (same as -gcutil), with the cause of the last and
gcnew 新生代行為統計。Statistics of the behavior of the new generation.
gcnewcapacity 新生代與其相應的記憶體空間的統計。Statistics of the sizes of the new generations and its corresponding spaces.
gcold 年老代和永生代行為統計。Statistics of the behavior of the old and permanent generations.
gcoldcapacity 年老代行為統計。Statistics of the sizes of the old generation.
gcpermcapacity 永生代行為統計。Statistics of the sizes of the permanent generation.
printcompilation HotSpot編譯方法統計。HotSpot compilation method statistics.

option 引數詳解

1)-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 : 載入時間

2)-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 : 失敗方法的全限定名

3)-gc:垃圾回收堆的行為統計常用命令

$ jstat -gc 1262
 S0C    S1C     S0U     S1U   EC       EU        OC         OU        PC       PU         YGC    YGCT    FGC    FGCT     GCT   
26112.0 24064.0 6562.5  0.0   564224.0 76274.5   434176.0   388518.3  524288.0 42724.7    320    6.417   1      0.398    6.815

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 : 垃圾回收總消耗時間

$ jstat -gc 1262 2000 20    #這個命令意思就是每隔2000ms輸出1262的gc情況,一共輸出20次

4)-gccapacity:同-gc,不過還會輸出Java堆各區域使用到的最大、最小空間

$ jstat -gccapacity 1262
 NGCMN    NGCMX     NGC    S0C   S1C       EC         OGCMN      OGCMX      OGC        OC       PGCMN    PGCMX     PGC      PC         YGC    FGC 
614400.0 614400.0 614400.0 26112.0 24064.0 564224.0   434176.0   434176.0   434176.0   434176.0 524288.0 1048576.0 524288.0 524288.0    320     1  

NGCMN : 新生代佔用的最小空間

NGCMX : 新生代佔用的最大空間

OGCMN : 老年代佔用的最小空間

OGCMX : 老年代佔用的最大空間

OGC:當前年老代的容量 (KB)

OC:當前年老代的空間 (KB)

PGCMN : perm佔用的最小空間

PGCMX : perm佔用的最大空間

5)-gcutil:同-gc,不過輸出的是已使用空間佔總空間的百分比

$ jstat -gcutil 28920
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
 12.45   0.00  33.85   0.00   4.44  4       0.242     0    0.000    0.242

6)-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:當前垃圾回收的原因

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

8)-gcnewcapacity:新生代與其相應的記憶體空間的統計

$ jstat -gcnewcapacity 28920
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC        YGC   FGC 
 4194304.0  4194304.0  4194304.0 419392.0 419392.0 419392.0 419392.0  3355520.0  3355520.0     4     0

NGC:當前年輕代的容量 (KB)

S0CMX:最大的S0空間 (KB)

S0C:當前S0空間 (KB)

ECMX:最大eden空間 (KB)

EC:當前eden空間 (KB)

9)-gcold:統計舊生代的行為

$ jstat -gcold 28920
   PC       PU        OC           OU       YGC    FGC    FGCT     GCT   
1048576.0  46561.7   6291456.0     0.0      4      0      0.000    0.242

10)-gcoldcapacity:統計舊生代的大小和空間

$ jstat -gcoldcapacity 28920
   OGCMN       OGCMX        OGC         OC         YGC   FGC    FGCT     GCT   
  6291456.0   6291456.0   6291456.0   6291456.0     4     0    0.000    0.242

11)-gcpermcapacity:永生代行為統計

$ jstat -gcpermcapacity 28920
    PGCMN      PGCMX       PGC         PC      YGC   FGC    FGCT     GCT   
 1048576.0  2097152.0  1048576.0  1048576.0     4     0    0.000    0.242

12)-printcompilation:hotspot編譯方法統計

$ jstat -printcompilation 28920
    Compiled  Size  Type Method
    1291      78     1    java/util/ArrayList indexOf

Compiled:被執行的編譯任務的數量

Size:方法位元組碼的位元組數

Type:編譯型別

Method:編譯方法的類名和方法名。類名使用"/" 代替 "." 作為空間分隔符. 方法名是給出類的方法名. 格式是一致於HotSpot - XX:+PrintComplation 選項

 

二、jmap

  jmap(JVM Memory Map)命令用於生成heap dump檔案,如果不使用這個命令,還可以使用-XX:+HeapDumpOnOutOfMemoryError引數來讓虛擬機器出現OOM的時候自動生成dump檔案。還可以查詢finalize執行佇列、Java堆和永久代的詳細資訊,如當前使用率、當前使用的是哪種收集器等。

命令格式

jmap [option] LVMID

option引數

dump : 生成堆轉儲快照

finalizerinfo : 顯示在F-Queue佇列等待Finalizer執行緒執行finalizer方法的物件

heap : 顯示Java堆詳細資訊

histo : 顯示堆中物件的統計資訊

permstat : to print permanent generation statistics

F : 當-dump沒有響應時,強制生成dump快照

1)-dump

常用格式:

-dump::live,format=b,file=<filename> pid 

dump堆到檔案,format指定輸出格式,live指明是活著的物件,file指定檔名。

$ jmap -dump:live,format=b,file=dump.hprof 28920
  Dumping heap to /home/xxx/dump.hprof ...
  Heap dump file created

dump.hprof這個字尾是為了後續可以直接用MAT(Memory Anlysis Tool)開啟。

2)-finalizerinfo:列印等待回收物件的資訊

$ 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方法的物件。

3)-heap:列印heap的概要資訊,GC使用的演算法,heap的配置及wise heap的使用情況,可以用此來判斷記憶體目前的使用情況以及垃圾回收情況。

$ 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.

4)-histo:列印堆的物件統計,包括物件數、記憶體大小等等 (因為在dump:live前會進行full gc,如果帶上live則只統計活物件,因此不加live的堆大小要大於加live堆的大小 )

$ jmap -histo:live 28920 | more
 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
  ....

僅僅列印了前10行,xml class name是物件型別,說明如下:

B  byte
C  char
D  double
F  float
I  int
J  long
Z  boolean
[  陣列,如[I表示int[]
[L+類名 其他物件

5)-permstat:列印Java堆記憶體的永久儲存區域的類載入器的智慧統計資訊。對於每個類載入器而言,它的名稱、活躍度、地址、父類載入器、它所載入的類的數量和大小都會被列印,此外,包含的字串數量和大小也會被列印。

$ jmap -permstat 28920
  Attaching to process ID 28920, please wait...
  Debugger attached successfully.
  Server compiler detected.
  JVM version is 24.71-b01
  finding class loader instances ..done.
  computing per loader stat ..done.
  please wait.. computing liveness.liveness analysis may be inaccurate ...
  
  class_loader            classes bytes   parent_loader           alive?  type  
  <bootstrap>             3111    18154296          null          live    <internal>
  0x0000000600905cf8      1       1888    0x0000000600087f08      dead    sun/reflect/DelegatingClassLoader@0x00000007800500a0
  0x00000006008fcb48      1       1888    0x0000000600087f08      dead    sun/reflect/DelegatingClassLoader@0x00000007800500a0
  0x00000006016db798      0       0       0x00000006008d3fc0      dead    java/util/ResourceBundle$RBClassLoader@0x0000000780626ec0
  0x00000006008d6810      1       3056      null          dead    sun/reflect/DelegatingClassLoader@0x00000007800500a0

6)-F:強制模式。如果指定的pid沒有響應,請使用jmap -dump或jmap -histo選項。此模式下,不支援live子選項。

 

三、jstack

  jstack用於生成java虛擬機器當前時刻的執行緒快照。執行緒快照是當前java虛擬機器內每一條執行緒正在執行的方法堆疊的集合,生成執行緒快照的主要目的是定位執行緒出現長時間停頓的原因,如執行緒間死鎖、死迴圈、請求外部資源導致的長時間等待等。 執行緒出現停頓的時候通過jstack來檢視各個執行緒的呼叫堆疊,就可以知道沒有響應的執行緒到底在後臺做什麼事情,或者等待什麼資源。 如果java程式崩潰生成core檔案,jstack工具可以用來獲得core檔案的java stack和native stack的資訊,從而可以輕鬆地知道java程式是如何崩潰和在程式何處發生問題。另外,jstack工具還可以附屬到正在執行的java程式中,看到當時執行的java程式的java stack和native stack的資訊,如果現在執行的java程式呈現hung的狀態,jstack是非常有用的。

命令格式

jstack [option] LVMID

option引數解釋:

-F : 當正常輸出請求不被響應時,強制輸出執行緒堆疊

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

-m : 如果呼叫到本地方法的話,可以顯示C/C++的堆疊

示例:

$ jstack -l 11494|more
2016-07-28 13:40:04
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.71-b01 mixed mode):

"Attach Listener" daemon prio=10 tid=0x00007febb0002000 nid=0x6b6f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"http-bio-8005-exec-2" daemon prio=10 tid=0x00007feb94028000 nid=0x7b8c waiting on condition [0x00007fea8f56e000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000cae09b80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None
      .....

分析:需要傳送到另一篇文章——http://www.hollischuang.com/archives/110

--------------------------------------------------------------------分割線----------------------------------------------------------

  關於jvm的東西,是做效能測試必需的東西。暫時先看這三個命令,我電腦沒帶Linux環境,用實驗樓的效果也不明顯,有條件的最好在自己電腦上敲一遍,然後慢慢看過去。

  先寫到這裡了,下午拔完智齒,現在整個人都是不好的狀態,以後誰跟我說拔智齒不疼,我就要錘爆他的頭!~!

相關文章