JVM經常使用命令解析

命令行:html

  1. jps:虛擬機進程情況工具
  2. jstat:虛擬機統計信息監視工具
  3. jinfo:java配置信息工具
  4. jmap:java內存映射工具
  5. jhat:虛擬機堆轉儲快照分析工具
  6. jstack:java堆棧跟蹤工具
  7. hsdis:jit生成代碼反編匯
  8. 目錄:D:\Program Files\jdk1.8.0_05\bin
  9. strace命令

可視化工具:java

  1. jconsole:java監視與管理控制檯
  2. visualvm:多合一故障處理工具

 

1、jpsc++

http://www.javashuo.com/article/p-mcdyfjuq-gh.html服務器

 jps是jdk提供的一個查看當前java進程的小工具, 能夠看作是JavaVirtual Machine Process Status Tool的縮寫。很是簡單實用。網絡

       命令格式:jps [options ] [ hostid ] 多線程

       [options]選項 :框架

-q:僅輸出VM標識符,不包括classname,jar name,arguments in main method jvm

-m:輸出main method的參數 ide

-l:輸出徹底的包名,應用主類名,jar的徹底路徑名 工具

-v:輸出jvm參數 

-V:輸出經過flag文件傳遞到JVM中的參數(.hotspotrc文件或-XX:Flags=所指定的文件 

-Joption:傳遞參數到vm,例如:-J-Xms512m

        [hostid]:

[protocol:][[//]hostname][:port][/servername]

        命令的輸出格式 :

lvmid [ [ classname| JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]

 

注意:若是須要查看其餘機器上的jvm進程,須要在待查看機器上啓動jstatd。

 

2、jstat

定義:

https://blog.csdn.net/zhaozheng7758/article/details/8623549

參數:

l  class (類加載器) 

l  compiler (JIT) 

l  gc (GC堆狀態) 

l  gccapacity (各區大小) 

l  gccause (最近一次GC統計和緣由) 

l  gcnew (新區統計)

l  gcnewcapacity (新區大小)

l  gcold (老區統計)

l  gcoldcapacity (老區大小)

l  gcpermcapacity (永久區大小)

l  gcutil (GC統計彙總)

l  printcompilation (HotSpot編譯統計)

 

jstat -gc 統計GC信息

一些術語的中文解釋: 

S0C:年輕代中第一個survivor(倖存區)的容量 (字節) 

S1C:年輕代中第二個survivor(倖存區)的容量 (字節) 

S0U:年輕代中第一個survivor(倖存區)目前已使用空間 (字節) 

S1U:年輕代中第二個survivor(倖存區)目前已使用空間 (字節) 

EC:年輕代中Eden(伊甸園)的容量 (字節) 

EU:年輕代中Eden(伊甸園)目前已使用空間 (字節) 

OC:Old代的容量 (字節) 

OU:Old代目前已使用空間 (字節) 

PC:Perm(持久代)的容量 (字節) 

PU:Perm(持久代)目前已使用空間 (字節) 

YGC:從應用程序啓動到採樣時年輕代中gc次數 

YGCT:從應用程序啓動到採樣時年輕代中gc所用時間(s) 

FGC:從應用程序啓動到採樣時old代(全gc)gc次數 

FGCT:從應用程序啓動到採樣時old代(全gc)gc所用時間(s) 

GCT:從應用程序啓動到採樣時gc用的總時間(s) 

 

jstat -gccapacity <pid>:

能夠顯示,VM內存中三代(young,old,perm)對象的使用和佔用大小

 

 

 

指定java程序運行內存大小

-Xms -Xmx -Xmn 等,而後觀察jstat的結果

 

增長gc參數,java程序自動輸出gc日誌

vm option: -Xms20M -Xmx20M -Xmn10M

-verbose:gc -XX:+PrintGCDetails -XX:SurvivorRatio=8

說明:

-XX:+PrintGCDetails參數用於告訴虛擬機在發生垃圾收集行爲時打印內存回收日誌,而且在進程退出的時候輸出當前內存的各區域分配狀況。

輸出日誌:

[GC (System.gc()) [PSYoungGen: 7497K->64K(236032K)] 35038K->27604K(1022464K), 0.0022938 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 64K->0K(236032K)] [ParOldGen: 27540K->27540K(786432K)] 27604K->27540K(1022464K), [Metaspace: 40881K->40881K(1087488K)], 0.0429459 secs] [Times: user=0.09 sys=0.00, real=0.04 secs]

 

https://www.cnblogs.com/xuezhiyizu1120/p/6237510.html

使用jinfo動態修改程序gc參數,協助調試

jinfo -flag +PrintGCDetails <pid>

jinfo -flag +PrintGC <pid>

jinfo -flag +PrintGCTimeStamps 輸出GC的時間戳(以基準時間的形式)

jinfo -flag +PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)

jinfo -flag +PrintHeapAtGC 在進行GC的先後打印出堆的信息

jinfo -flag -Xloggc:../logs/gc.log 日誌文件的輸出路徑

-verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log

 

-Xms100m -Xmx100m -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -verbose:gc -Xloggc:/usr/local/e6atlasbus/canbus/canbus-server/gc_logs/gc.log

 

更改gc參數

https://www.cnblogs.com/gouge/p/9112782.html

 

3、jinfo

jinfo 是jdk自帶的一個工具,它能夠用來查看正在運行的java應用程序的擴展參數(JVM中-X標示的參數);甚至支持在運行時修改部分參數。

jinfo 223536 > tmp/jinfo.txt 獲取jvm進程的全部信息

關鍵字:VM Flags

動態修改命令:

經過如下的命令你便能看到JVM中哪些flag能夠被jinfo動態修改:

java -XX:+PrintFlagsFinal -version | grep manageable

 

https://blog.csdn.net/liuxiao723846/article/details/72701414

 

4、jmap

jmap命令(Java Memory Map)是其中之一。主要用於打印指定Java進程(或核心文件、遠程調試服務器)的共享對象內存映射或堆內存細節。

 

jmap命令能夠得到運行中的jvm的堆的快照,從而能夠離線分析堆,以檢查內存泄漏,檢查一些嚴重影響性能的大對象的建立,檢查系統中什麼對象最多,各類對象所佔內存的大小等等。可使用jmap生成Heap Dump。 

java memory = direct memory(直接內存) + jvm memory(MaxPermSize +Xmx)

 

JVM直接內存:

直接內存區並非 JVM 管理的內存區域的一部分,而是其以外的。該區域也會在 Java 開發中使用到,而且存在致使內存溢出的隱患。

https://blog.csdn.net/leaf_0303/article/details/78961936

深刻理解JVM之JVM內存區域與內存分配

http://www.javashuo.com/article/p-zzsvwufz-o.html

 

經常使用命令:

jmap -heap <pid> 查看堆內存

jmap -histo:live <pid> 查看對內對象

jmap -dump:live,format=b,file=/f/dump.dat <pid> 導出堆快照

jhat /f/dump.dat 分析dump文件

 

https://www.cnblogs.com/kongzhongqijing/articles/3621163.html

 

dump文件分析

jvisualvm

OQL 分析dump文件 https://www.aliyun.com/jiaocheng/299417.html

select x from com.e6yun.preprocessor.processor.jcmd.JCmdObject x

 

dump文件中的線程分析->jstack命令

 

總結

1.若是程序內存不足或者頻繁GC,頗有可能存在內存泄露狀況,這時候就要藉助Java堆Dump查看對象的狀況。

2.要製做堆Dump能夠直接使用jvm自帶的jmap命令

3.能夠先使用jmap -heap命令查看堆的使用狀況,看一下各個堆空間的佔用狀況。

4.使用jmap -histo:[live]查看堆內存中的對象的狀況。若是有大量對象在持續被引用,並無被釋放掉,那就產生了內存泄露,就要結合代碼,把不用的對象釋放掉。

5.也可使用 jmap -dump:format=b,file=<fileName>命令將堆信息保存到一個文件中,再借助jhat命令查看詳細內容

6.在內存出現泄露、溢出或者其它前提條件下,建議多dump幾回內存,把內存文件進行編號歸檔,便於後續內存整理分析。

7.在用cms gc的狀況下,執行jmap -heap有些時候會致使進程變T,所以強烈建議別執行這個命令,若是想獲取內存目前每一個區域的使用情況,可經過jstat -gc或jstat -gccapacity來拿到。

 

5、jhat

jhat也是jdk內置的工具之一。主要是用來分析java堆的命令,能夠將堆中的對象以html的形式顯示出來,包括對象的數量,大小等等,並支持對象查詢語言。

https://www.cnblogs.com/baihuitestsoftware/articles/6406271.html

 

jhat /f/dump.dat 分析dump文件

使用jvisualvm可視化工具替代

 

6、jstack

jstack命令主要用生成java虛擬機當前時刻的線程快照,來查看Java線程的調用堆棧的,能夠用來分析線程問題(如死鎖)。

http://www.cnblogs.com/kongzhongqijing/articles/3630264.html

 

命令格式:

jstack [ option ] pid

jstack [ option ] executable core

jstack [ option ] [server-id@]remote-hostname-or-IP

 

經常使用參數說明

1)options: 

executable Java executable from which the core dump was produced.(多是產生core dump的java可執行程序)

core 將被打印信息的core dump文件

remote-hostname-or-IP 遠程debug服務的主機名或ip

server-id 惟一id,假如一臺主機上多個遠程debug服務 

2)基本參數:

-F 當’jstack [-l] pid’沒有相應的時候強制打印棧信息,若是直接jstack無響應時,用於強制jstack),通常狀況不須要使用

-l 長列表. 打印關於鎖的附加信息,例如屬於java.util.concurrent的ownable synchronizers列表,會使得JVM停頓得長久得多(可能會差不少倍,好比普通的jstack可能幾毫秒和一次GC沒區別,加了-l 就是近一秒的時間),-l 建議不要用。通常狀況不須要使用

-m 打印java和native c/c++框架的全部棧信息.能夠打印JVM的堆棧,顯示上Native的棧幀,通常應用排查不須要使用

-h | -help 打印幫助信息

pid 須要被打印配置信息的java進程id,能夠用jps查詢.

 

線程狀態:

NEW

未啓動的。不會出如今Dump中。

RUNNABLE

在虛擬機內執行的。運行中狀態,可能裏面還能看到locked字樣,代表它得到了某把鎖。

BLOCKED

受阻塞並等待監視器鎖。被某個鎖(synchronizers)給block住了。

WATING

無限期等待另外一個線程執行特定操做。等待某個condition或monitor發生,通常停留在park(), wait(), sleep(),join() 等語句裏。

TIMED_WATING

有時限的等待另外一個線程的特定操做。和WAITING的區別是wait() 等語句加上了時間限制 wait(timeout)。

TERMINATED

已退出的。

 

Monitor

在多線程的 JAVA程序中,實現線程之間的同步,就要說說 Monitor。 Monitor是 Java中用以實現線程之間的互斥與協做的主要手段,它能夠當作是對象或者 Class的鎖。每個對象都有,也僅有一個 monitor。這就是wait,notify等方法在Object類的緣由。

 

調用修飾

表示線程在方法調用時,額外的重要的操做。線程Dump分析的重要信息。修飾上方的方法調用。

locked <地址> 目標:使用synchronized申請對象鎖成功,監視器的擁有者。

waiting to lock <地址> 目標:使用synchronized申請對象鎖未成功,在迚入區等待。

waiting on <地址> 目標:使用synchronized申請對象鎖成功後,釋放鎖幵在等待區等待。

parking to wait for <地址> 目標

 

線程動做,線程狀態產生的緣由

runnable:狀態通常爲RUNNABLE。

in Object.wait():等待區等待,狀態爲WAITING或TIMED_WAITING。

waiting for monitor entry:進入區等待,狀態爲BLOCKED。

waiting on condition:等待區等待、被park。

sleeping:休眠的線程,調用了Thread.sleep()。

 

jstack 解決問題實例

http://www.iteye.com/topic/1114219

http://note.youdao.com/noteshare?id=4e05478b110f1d22fbaeb3a740671a00

 

分析問題入手點總結:

wait on monitor entry: 被阻塞的,確定有問題

runnable : 注意IO線程

in Object.wait(): 注意非線程池等待

 

分析經驗:

對於jstack作的ThreadDump的棧,能夠反映以下信息:

  1. 若是某個相同的call stack常常出現, 咱們有80%的以上的理由肯定這個代碼存在性能問題(讀網絡的部分除外);
  2. 若是相同的call stack出如今同一個線程上(tid)上, 咱們很很大理由相信, 這段代碼可能存在較多的循環或者死循環;
  3. 若是某call stack常常出現, 而且裏面帶有lock,請檢查一下這個lock的產生的緣由, 多是全局lock形成了性能問題;
  4. 在一個不大壓力的羣集裏(w<2), 咱們是不多拿到帶有業務代碼的stack的, 而且通常在一個完整stack中, 最多隻有1-2業務代碼的stack,
  5. 若是常常出現, 必定要檢查代碼, 是否出現性能問題。
  6. 若是你懷疑有dead lock問題, 那麼請把全部的lock id找出來,看看是否是出現重複的lock id。

 

頻繁GC問題或內存溢出問題

1、使用jps查看線程ID

2、使用jstat -gc 3331 250 20 查看gc狀況,通常比較關注PERM區的狀況,查看GC的增加狀況。

3、使用jstat -gccause:額外輸出上次GC緣由

4、使用jmap -dump:format=b,file=heapDump 3331生成堆轉儲文件

5、使用jhat或者可視化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)分析堆狀況。

6、結合代碼解決內存溢出或泄露問題。

 

死鎖問題

1、使用jps查看線程ID

2、使用jstack 3331:查看線程狀況

 

6、hsdis

相關文章
相關標籤/搜索