JVM學習(三)JVM經常使用命令

我的博客項目地址html

但願各位幫忙點個star,給我加個小星星✨java


本篇記錄JVM經常使用的指令,經過Java的bin目錄下強大的工具就能進行查看。linux

其中不少命令參考option參數,本身要多敲幾遍才能記住。git


JVM經常使用命令

其中[]方括號內的參數,表示無關緊要。github


jps


JVM Process Status Tool,顯示指定系統內全部的HotSpot虛擬機進程。web

命令格式算法

jps [option] [hostid]
複製代碼

option參數apache

-l : 輸出主類全名或jar路徑
-q : 只輸出LVMID
-m : 輸出JVM啓動時傳遞給main()的參數
-v : 輸出JVM啓動時顯示指定的JVM參數
複製代碼

示例:centos

[root@VM_247_254_centos ~]#jps -lm
26176 org.apache.zookeeper.server.quorum.QuorumPeerMain /usr/local/zookeeper-3.4.10/bin/../conf/zoo.cfg
25044 /usr/local/apache-activemq-5.14.5//bin/activemq.jar start
23732 sun.tools.jps.Jps -lm
25446 org.apache.catalina.startup.Bootstrap start
複製代碼

最前面數字表示PID,後面有用到。瀏覽器


jstat


jstat(JVM statistics Monitoring)是用於監視虛擬機運行時狀態信息的命令,它能夠顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。

命令格式

jstat [option] LVMID [interval] [count]

[option] : 操做參數
LVMID : 本地虛擬機進程ID
[interval] : 連續輸出的時間間隔
[count] : 連續輸出的次數
複製代碼

option參數

Option 解釋
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.

例如查看垃圾回收堆的行爲統計

[root@VM_247_254_centos ~]# jstat -gc 25446
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
6400.0 6400.0  0.0   1601.4 51712.0  50837.0   128808.0   88450.0   67584.0 66167.7 7936.0 7630.5    401    5.939  10      1.247    7.186
複製代碼

順便介紹一下參數意義: 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 : 垃圾回收總消耗時間
複製代碼

上面有不少個option參數,能夠一個個敲過去看看具體的做用。


jmap


jmap(JVM Memory Map)命令用於生成heap dump文件,若是不使用這個命令,可使用-XX:+HeapDumpOnOutOfMemoryError參數來讓虛擬機出現OOM的時候,自動生成dump文件。 jmap不只能生成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快照
複製代碼

舉個🌰

  • -dump
jmap -dump:format=b,file=dump.dprof 25446
Dumping heap to /home/gem/dump.dprof ...
Heap dump file created
複製代碼

輸出.dprof文件後,使用MAT分析工具進行分析

  • -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用狀況,能夠用此來判斷內存目前的使用狀況以及垃圾回收狀況
jmap -heap 25446
Attaching to process ID 25446, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13

using thread-local object allocation.
Mark Sweep Compact GC  //GC 方式 ,該次是標記-清理算法,上一篇有記錄哦

//堆內存初始化配置
Heap Configuration:  
   //對應jvm啓動參數-XX:MinHeapFreeRatio設置JVM堆最小空閒比率(default 40)
   MinHeapFreeRatio         = 40   
   //對應jvm啓動參數 -XX:MaxHeapFreeRatio設置JVM堆最大空閒比率(default 70)
   MaxHeapFreeRatio         = 70
   //對應jvm啓動參數-XX:MaxHeapSize=設置JVM堆的最大大小
   MaxHeapSize              = 262144000 (250.0MB)
   //對應jvm啓動參數-XX:NewSize=設置JVM堆的‘新生代’的默認大小
   NewSize                  = 5570560 (5.3125MB)
   //對應jvm啓動參數-XX:MaxNewSize=設置JVM堆的‘新生代’(YG)的最大大小
   MaxNewSize               = 87359488 (83.3125MB)
   //對應jvm啓動參數-XX:OldSize=<value>:設置JVM堆的‘老生代’(OG)的大小
   OldSize                  = 11206656 (10.6875MB)
   //對應jvm啓動參數-XX:NewRatio=:‘新生代’和‘老年代’的大小比率
   NewRatio                 = 2
   //對應jvm啓動參數-XX:SurvivorRatio=設置年輕代中Eden區與Survivor區的大小比值 
   SurvivorRatio            = 8
   //元空間大小,對應-XX:MetaspaceSize,初始空間大小
   //達到該值就會觸發垃圾收集進行類型卸載,同時GC會對該值進行調整
   //JDK 8 中永久代向元空間的轉換
   MetaspaceSize            = 21807104 (20.796875MB)
   //只有當-XX:+UseCompressedClassPointers開啓了纔有效
   //經過java -XX:+PrintFlagsInitial | grep UseCompressedClassPointers
   //發現bool UseCompressedClassPointers= false,是沒有啓用的
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   //對應啓動參數-XX:MaxMetaspaceSize對應元空間最大大小
   MaxMetaspaceSize         = 17592186044415 MB
   //當使用G1收集器時,設置java堆被分割的大小。這個大小範圍在1M到32M之間。
   //可能我這個JVM沒有啓用G1收集器,因此爲0
   G1HeapRegionSize         = 0 (0.0MB)

//堆內存使用狀況
Heap Usage:
//新的複製算法,一個伊甸區+Survivor區
New Generation (Eden + 1 Survivor Space):
   capacity = 59506688 (56.75MB)
   used     = 17941224 (17.110084533691406MB)
   free     = 41565464 (39.639915466308594MB)
   30.14992869372935% used
//Eden區內存分佈
Eden Space:
   capacity = 52953088 (50.5MB)
   used     = 17935840 (17.104949951171875MB)
   free     = 35017248 (33.395050048828125MB)
   33.871188022122524% used
//其中一個Survivor區的內存分佈
From Space:
   capacity = 6553600 (6.25MB)
   used     = 5384 (0.00513458251953125MB)
   free     = 6548216 (6.244865417480469MB)
   0.0821533203125% used
//另外一個Survivor區的內存分佈
To Space:
   capacity = 6553600 (6.25MB)
   used     = 0 (0.0MB)
   free     = 6553600 (6.25MB)
   0.0% used
//‘當前’老年代內存分佈
tenured generation:
   capacity = 131899392 (125.7890625MB)
   used     = 94610832 (90.22792053222656MB)
   free     = 37288560 (35.56114196777344MB)
   71.7295436812931% used

27405 interned Strings occupying 3101144 bytes.
複製代碼

jhat

jhat(JVM Heap Analysis Tool)命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內置了一個微型的HTTP/HTML服務器,生成dump的分析結果後,能夠在瀏覽器中查看。在此要注意,通常不會直接在服務器上進行分析,由於jhat是一個耗時而且耗費硬件資源的過程,通常把服務器生成的dump文件複製到本地或其餘機器上進行分析。

由於經常使用分析方法是用各平臺通用的MAT進行分析,就不具體在遠程服務器操做展現效果了。


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 25446 | more
2018-01-25 21:18:22
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):

"main-EventThread" #174 daemon prio=5 os_prio=0 tid=0x00007feb692b7000 nid=0x6502 waiting on condition [0x00007feb32bb1000]
    //等待
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000f0a00860> (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.ClientCnxn$EventThread.run(ClientCnxn.java:501)

   Locked ownable synchronizers:
	- None

"main-SendThread(115.159.192.69:2181)" #173 daemon prio=5 os_prio=0 tid=0x00007feb694bd800 nid=0x6501 runnable [0x00007feb363ce000]
    //運行
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
	at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
	at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
	- locked <0x00000000f09ef268> (a sun.nio.ch.Util$3)
	- locked <0x00000000f09ef258> (a java.util.Collections$UnmodifiableSet)
	- locked <0x00000000f09ef140> (a sun.nio.ch.EPollSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
	at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:349)
	at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1141)

   Locked ownable synchronizers:
	- None
複製代碼

jinfo

jinfo(JVM Configuration info)這個命令做用是實時查看和調整虛擬機運行參數。 以前的jps -v口令只能查看到顯示指定的參數,若是想要查看未被顯示指定的參數的值就要使用jinfo口令

通常我經常使用它來看JVM啓動時的參數

命令格式

jinfo [option] [args] LVMID
複製代碼

optin參數

-flag     : 輸出指定args參數的值
-flags    : 不須要args參數,輸出全部JVM參數的值
-sysprops : 輸出系統屬性,等同於System.getProperties()
複製代碼

舉個🌰

[root@VM_247_254_centos ~]# jinfo -flags 25446
Attaching to process ID 25446, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=16777216 -XX:MaxHeapSize=262144000 -XX:MaxNewSize=87359488 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=5570560 -XX:OldSize=11206656 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
Command line:  -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp
複製代碼

從上面能夠看到,jinfo打印出來的參數,下一篇本來想寫MAT的使用,可是本身手動製造過異常,異常信息集中在Java Objects,只要聯想到跟上一次改動過的代碼,就能發現大對象可能出現的地方,因此具體分析的話,等以後拿到比較複雜的dump文件再具體學習。


參考資料

一、《jvm系列(四):jvm調優-命令大全(jps jstat jmap jhat jstack jinfo)》

二、Java8內存模型—永久代(PermGen)和元空間(Metaspace)

三、周志明的《深刻理解JVM》

相關文章
相關標籤/搜索