天天看點

java常用工具相關資料jps 簡介jinfo 簡介jstatd 簡介jstat 簡介jstack 簡介jmap 簡介jhat 簡介jdb簡介jconsole簡介jvisualvm 簡介常見問題

相關資料

  • jstat java性能統計工具
  • jstack java線程堆棧工具
  • jmap java記憶體映像工具
  • jps java程序檢視
  • jinfo java配置資訊工具
  • jhat java堆快照分析工具
  • jconsole 可視化java工具
  • jvisualvm 可視化java工具
  • jstatd java統計監控背景程式
  • jdb java調試工具

jps 簡介

列出所有java程序

options

-q 僅輸出VM辨別符,不包括class name,jar name,arguments in main method 
-m 輸出main method的參數 
-l 輸出完全的包名,應用主類名,jar的完全路徑名 
-v 輸出jvm參數 
-V 輸出通過flag檔案傳遞到JVM中的參數(.hotspotrc檔案或-XX:Flags=所指定的檔案 
-Joption 傳遞參數到vm,例如:-J-Xms48m
           

hostid

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

Examples

jps rmi:.*.*.*:   #  檢視遠端機器的java程序id(需要遠端開啟jstatd程序)
jps -lmv                #  本地java程序的詳細資訊
           

jinfo 簡介

jinfo可以輸出并修改運作時的java 程序的opts。用處比較簡單,用于輸出JAVA系統參數及指令行參數。一般不支援修改,jdk8廢棄改指令。

jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [server[email protected]]remote-hostname-or-IP 
           

Options

no option  列印指令行參數和系統屬性
-flags  列印指令行參數
-sysprops  列印系統屬性
-h  幫助
           

jstatd 簡介

虛拟機的監控的守護程序,主要用于監控JVM的建立與終止,并提供一個接口允許遠端監控工具(jps|jstat|jstack…)依附到在本地主機上運作的JVM。

Options

-nr 當一個存在的RMI Registry沒有找到時,不嘗試建立一個内部的RMI Registry
-p port 端口号,預設為
-n rminame 預設為JStatRemoteHost;如果多個jstatd服務開始在同一台主機上,rminame唯一确定一個jstatd服務
-J jvm選項
           

Usages

  • 通過政策檔案(jstatd.all.policy),允許jstatd伺服器在沒有任何安全例外的情況下運作。該政策沒有授權所有權限給所有代碼庫那麼自由,但卻比授予最小的權限來運作jstatd伺服器更自由.個人建議要及時關閉,有風險。
grant codebase "file:${java.home}/../lib/tools.jar" {  
   permission java.security.AllPermission;  
};
           
  • 基于政策檔案,啟動jstatd,同時啟動RMI日志(一般沒必要就不要開啟了)
nohup rmiregistry &jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.logCalls=true -p   &
           

jstat 簡介

jvm監控統計工具,包括gc資訊,類編譯資訊等。

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
           

vmid

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

options

-class 類加載情況的統計
Loaded 加載了的類的數量
Bytes 加載了的類的大小,單為Kb
Unloaded 解除安裝了的類的數量
Bytes 解除安裝了的類的大小,單為Kb
Time 花在類的加載及解除安裝的時間
-compiler HotSpot中即時編譯器編譯情況的統計
Compiled 編譯任務執行的次數
Failed 編譯任務執行失敗的次數
Invalid 編譯任務非法執行的次數
Time 執行編譯花費的時間
FailedType 最後一次編譯失敗的編譯類型
FailedMethod 最後一次編譯失敗的類名及方法名
-gc JVM中堆的垃圾收集情況的統計
S0C 新生代中Survivor space中S0目前容量的大小(KB)
S1C 新生代中Survivor space中S1目前容量的大小(KB)
S0U 新生代中Survivor space中S0容量使用的大小(KB)
S1U 新生代中Survivor space中S1容量使用的大小(KB)
EC Eden space目前容量的大小(KB)
EU Eden space容量使用的大小(KB)
OC Old space目前容量的大小(KB)
OU Old space使用容量的大小(KB)
PC Permanent space目前容量的大小(KB)
PU Permanent space使用容量的大小(KB)
YGC 從應用程式啟動到采樣時發生 Young GC 的次數
YGCT 從應用程式啟動到采樣時 Young GC 所用的時間(秒)
FGC 從應用程式啟動到采樣時發生 Full GC 的次數
FGCT 從應用程式啟動到采樣時 Full GC 所用的時間(秒)
GCT T從應用程式啟動到采樣時用于垃圾回收的總時間(機關秒),它的值等于YGC+FGC
-gccapacity 新生代、老生代及持久代的存儲容量情況
NGCMN 新生代的最小容量大小(KB)
NGCMX 新生代的最大容量大小(KB)
NGC 目前新生代的容量大小(KB)
S0C 目前新生代中survivor space 0的容量大小(KB)
S1C 目前新生代中survivor space 1的容量大小(KB)
EC Eden space目前容量的大小(KB)
OGCMN 老生代的最小容量大小(KB)
OGCMX 老生代的最大容量大小(KB)
OGC 目前老生代的容量大小(KB)
OC 目前老生代的空間容量大小(KB)
PGCMN 持久代的最小容量大小(KB)
PGCMX 持久代的最大容量大小(KB)
PGC 目前持久代的容量大小(KB)
PC 目前持久代的空間容量大小(KB)
YGC 從應用程式啟動到采樣時發生 Young GC 的次數
FGC 從應用程式啟動到采樣時發生 Full GC 的次數
-gccause 這個選項用于檢視垃圾收集的統計情況(這個和-gcutil選項一樣),如果有發生垃圾收集,它還會顯示最後一次及目前正在發生垃圾收集的原因,它比-gcutil會多出最後一次垃圾收集原因以及目前正在發生的垃圾收集的原因。用于檢視垃圾收集的統計情況,包括最近發生垃圾的原因
LGCC 最後一次垃圾收集的原因,可能為“unknown GCCause”、“System.gc()”等
GCC 目前垃圾收集的原因
-gcutil 新生代、老生代及持代垃圾收集的情況
S0 Heap上的 Survivor space 0 區已使用空間的百分比
S1 Heap上的 Survivor space 1 區已使用空間的百分比
E Heap上的 Eden space 區已使用空間的百分比
O Heap上的 Old space 區已使用空間的百分比
P Perm space 區已使用空間的百分比
YGC 從應用程式啟動到采樣時發生 Young GC 的次數
YGCT 從應用程式啟動到采樣時 Young GC 所用的時間(機關秒)
FGC 從應用程式啟動到采樣時發生 Full GC 的次數
FGCT 從應用程式啟動到采樣時 Full GC 所用的時間(機關秒)
GCT 從應用程式啟動到采樣時用于垃圾回收的總時間(機關秒),它的值等于YGC+FGC
-printcompilation HotSpot編譯方法的統計
Compiled 編譯任務執行的次數
Size 方法的位元組碼所占的位元組數
Type 編譯類型
Method 指定确定被編譯方法的類名及方法名,類名中用“/”而不是“.”做為命名分隔符,方法名是被指定的類中的方法,這兩個字段的格式是由HotSpot中的“-XX:+PrintComplation”選項确定的。
-JjavaOption 用于将給定的javaOption傳給java應用程式加載器,例如,“-J-Xms48m”将把啟動記憶體設定為48M。如果想檢視可以傳遞哪些選項到應用程式加載器中,可以相看如下的文檔
Linux and Solaris: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/solaris/java.html
Windows: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/java.html
-t n 用于在輸出内容的第一列顯示時間戳,這個時間戳代表的時JVM開始啟動到現在的時間
-h n 用于指定每隔幾行就輸出列頭,如果不指定,預設是隻在第一行出現列頭

Examples

jstat -gc rmi:pid@10.*.*.*:   #  檢視遠端機器 指定pid的gc 資訊
jstat -class  pid         #  本地java程序[pid]的類加載情況的統計
           

Reference

  • jvm記憶體結構及管理
  • jvm gc 詳情

jstack 簡介

jstack用于列印出給定的Java程序ID或core file或遠端調試服務的Java堆棧資訊,如果是在64位機器上,需要指定選項”-J-d64”,Windows的jstack使用方式隻支援以下的這種方式:jstack [-l] pid

如果java程式崩潰生成core檔案,jstack工具可以用來獲得core檔案的java stack和native stack的資訊,進而可以輕松地知道java程式是如何崩潰和在程式何處發生問題。另外,jstack工具還可以附屬到正在運作的java程式中,看到當時運作的java程式的java stack和native stack的資訊, 如果現在運作的java程式呈現hung的狀态,jstack是非常有用的。

jstack [ option ] pid                    #(Usually)
jstack [ option ] executable core
jstack [ option ] [[email protected]]remote-hostname-or-IP
           

Option

-F          #當’jstack [-l] pid’沒有相應的時候強制列印棧資訊

-l          #長清單. 列印關于鎖的附加資訊,例如屬于java.util.concurrent的ownable synchronizers清單.

-m          #列印java和native c/c++架構的所有棧資訊.

-h|-help    #列印幫助資訊
           

jstack内容詳解

  • java線程狀态
  • java線程狀态轉移
    java常用工具相關資料jps 簡介jinfo 簡介jstatd 簡介jstat 簡介jstack 簡介jmap 簡介jhat 簡介jdb簡介jconsole簡介jvisualvm 簡介常見問題
 線程被阻塞可能是由于下面五方面的原因:

  1.調用sleep(毫秒數),使線程進入睡眠狀态。在規定時間内,這個線程是不會運作的。
  2.用suspend()暫停了線程的執行。除非收到resume()消息,否則不會傳回“可運作”狀态。(已廢棄)
  3.用wait()暫停了線程的執行。除非線程收到notify()或notifyAll()消息,否則不會變成“可運作”狀态。
  4.線程正在等候一些IO操作完成。
  5.線程試圖調用另一個對象的“同步”方法,但那個對象處于鎖定狀态,暫時無法使用。

  所涉及到的兩種池:

  Wait pool 等待池

  Lock pool 鎖池
           
  • jstack 幾種線程狀态介紹
Runnable                #包括runnable和running兩種狀态
Wait on condition       #線程等待IO,sleep等
Waiting for monitor entry #對象在Lockpool中 
in Object.wait()        #對象在wait pool 中需要notify才能進入鎖池,并最終獲得鎖進入Runnable狀态
           
  • jstack分析執行個體

jstack分析幾種常見問題

io異常

  • 當jstack dump 的線程中存在大量的 wait on condition ,觀察堆棧是不是網絡IO 導緻的,結合系統指令 netstat 觀察是不是已經超過帶寬的上限。
  • lsof -p $pid 觀察目前程序的io請況
  • iostat 觀察系統總體的io情況

死鎖

jstack 會自動識别并表示死鎖。

熱鎖

熱鎖,也往往是導緻系統性能瓶頸的主要因素。其表現特征為,由于多個線程對臨界區,或者鎖的競争,可能出現:

  • 頻繁的線程的上下文切換:從作業系統對線程的排程來看,當 線程在等待資源而阻塞的時候,作業系統會将之切換出來,放到等待的隊列,當線程獲得資源之後,排程算法會将這個線程切換進去,放到執行隊列中。
  • 大量的系統調用:因為線程的上下文切換,以及熱鎖的競争,或 者臨界區的頻繁的進出,都可能導緻大量的系統調用。
  • 大部分 CPU開銷用在 “系統态 ”:線程上下文切換,和系統調用,都會導緻 CPU在 “系統态 ”運作,換而言之,雖然系統很忙碌,但是 CPU用在 “使用者态 ”的比例較小,應用程式得不到充分的 CPU資源。
  • 随着 CPU數目的增多,系統的性能反而下降。因為 CPU數目多,同 時運作的線程就越多,可能就會造成更頻繁的線程上下文切換和系統态的 CPU開銷,進而導緻更糟糕的性能。

結合系統指令top -p $pid; shift +h ;以及具體堆棧分析定位系統态的cpu占用過高的具體原因。

cpu過高

  • 結合系統指令定位具體的程序中某個導緻程序cpu過高的線程pid。
  • printf(“%x\n”) $pid 轉換十六進制;對應堆棧中的nid(nid 是實際的本地系統的程序id,tid 是虛拟機中的程序id)。
  • 通過堆棧資訊,分析該線程pid的具體資訊。

程式效率低,執行慢

分析是否存在死鎖,熱鎖。分析WAITING,BLOCK,狀态的線程。觀察是不是IO導緻的,網絡IO,帶寬問題,還是網絡斷開導緻的空等待,還是線程sleep,waitpool中的對象是不是忘記喚醒,lockpool的對象是不是永遠擷取不到鎖,TIMED_WAIT設定的時間是否合理,或者磁盤IO導緻的,具體問題結合堆棧資訊和系統狀态進行分析。(vmstat,iostat,netstat,uptime,top。lsof等指令根據需要配合使用。)

jmap 簡介

列印出某個java程序記憶體的,所有‘對象’的情況。64位機器上,需要指定選項”-J-d64”。

jmap [ option ] pid                    #(Usually)
jmap [ option ] executable core
jmap [ option ] [[email protected]]remote-hostname-or-IP
           

Options

-dump:[live,]format=b,file=<filename> #使用hprof二進制形式,輸出jvm的heap内容到檔案。live子選項是可選的,假如指定live選項,那麼隻輸出活的對象到檔案. 
-finalizerinfo                        #列印正等候回收的對象的資訊.
-heap                                 #列印heap的概要資訊,GC使用的算法,heap的配置及wise heap的使用情況.
-histo[:live]                         #列印每個class的執行個體數目,記憶體占用,類全名資訊. VM的内部類名字開頭會加上字首”*”. 如果live子參數加上後,隻統計活的對象數量. 
-permstat                             #列印classload和jvm heap長久層的資訊. 包含每個classloader的名字,活潑性,位址,父classloader和加載的class數量. 另外,内部String的數量和占用記憶體數也會列印出來. 
-F                                    #強迫在pid沒有相應的時候使用-dump或者-histo參數. 在這個模式下,live子參數無效. 
-h | -help                            #列印輔助資訊 
-J                                    #傳遞參數給jmap啟動的jvm. 
           

Example

jmap  -dump:format=b,file=tomcat.bin 
jmap  -histo:live $cpid
           

jhat 簡介

用來分析Java堆的指令,可以将堆中的對象以html的形式顯示出來,包括對象的數量,大小等等,并支援對象查詢語言.

  • jhat tomcat.bin (jmap dump的檔案)
  • dump出來的堆很大,在啟動時會報堆空間不足的錯。添加 -J-Xmx512m,重定義最大堆記憶體
  • ip:7000 浏覽器檢視
  • http://ip:7000/histo/ 類大小,數量統計資訊
  • http://ip:7000/showRoots/ gc根集
  • http://ip:7000/oql/ 對象查詢
  • http://ip:7000/oqlhelp/ 對象查詢文法

jdb簡介

java debug 工具,一般使用IDE,debug更快捷,無界面程式可以使用該工具調試。

指令行調試

jdb調試指令

JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"
jdb -attach .:
           

jconsole簡介

JConsole 是一個内置 Java 性能分析器,可以從指令行或在 GUI shell 中運作。

Usages jconsole

jvisualvm 簡介

jconsole的更新版。

Usages jvisualvm

常見問題

sun.jvm.hotspot.debugger.DebuggerException 異常

出現場景

- jinfo pid

- jstack -F

- jmap -heap

Solve

sudo vim /etc/sysctl.d/-ptrace.conf 
修改 kernel.yama.ptrace_scope =  
sudo /sbin/sysctl -e -p  /etc/sysctl.d/-ptrace.conf 重新加載該調整資訊,無需重新開機,永久有效
echo  | sudo tee /proc/sys/kernel/yama/ptrace_scope 目前有效,重新開機後無效,建議使用後恢複本來的設定,ubuntu從後修改了該預設設定,應該是出于安全考慮,線上環境,更應該謹慎使用。
           

sun.jvm.hotspot.runtime.VMVersionMismatchException

工具和pid的jvm不一緻導緻的,使用啟動目前pid的java指令所在的檔案夾下的工具指令。