JVM学习笔记之-JVM性能监控-JVM监控及诊断工具-命令行方式
性能優化的步驟
第1步(發現問題):性能監控
一種以非強行或者入侵方式收集或查看應用運營性能數據的活動。
監控通常是指一種在生產、質量評估或者開發環境下實施的帶有預防或主動性的活動。
當應用相關干系人提出性能問題卻沒有提供足夠多的線索時,首先我們需要進行性能監控,隨后是性能分析。
列如:
GC頻繁 cpu load過高 OOM 內存泄漏 死鎖 程序響應時間較長
第2步(排查問題)∶性能分析
一種以侵入方式收集運行性能數據的活動,它會影響應用的香吐量或響應性。
性能分析是針對性能問題的答復結果,關注的范圍通常比性能監控更加集中。
性能分析很少在生產環境下進行,通常是在質量評估、系統測試或者開發環境下進行,是性能監控之后的步驟。
有如下調優:
打印GC日志,通過GCviewer或者http://gceasy.io來分析日志信息
靈活運用命令行工具,jstack, jmap, jinfo等
dump出堆文件,使用內存分析工具分析文件
使用阿里Arthas,或jconsole,JVisualVM來實時查看JVM狀態
jstack查看堆棧信息
第3步(解決問題):性能調優
一種為改善應用響應性或吞吐量而更改參數、源代碼、屬性配置的活動,性能調優是在性能監控、性能分析之后的活動。
適當增加內存,根據業務背景選擇垃圾回收器
優化代碼,控制內存使用
增加機器,分散節點壓力
合理設置線程池線程數量
使用中間件提高程序效率,比如緩存,消息隊列等
其他…
性能評價/測試指標
1-停頓時間(或響應時間)
2-吞吐量
3-并發數
4-內存占用
JVM監控及診斷工具-命令行
01-概述
概述
性能診斷是軟件工程師在日常工作中需要經常面對和解決的問題,在用戶體驗至上的今天,解決好應用的性能問題能帶來非常大的收益。
Java 作為最流行的編程語言之一,其應用性能診斷一直受到業界廣泛關注。可能造成Java應用出現性能問題的因素非常多,例如線程控制、磁盤讀寫、數據庫訪問、網絡I/0、垃圾收集等。想要定位這些問題,一款優秀的性能診斷工具必不可少。
體會1:使用數據說明問題,使用知識分析問題,使用工具處理問題。體會2:無監控、不調優!簡單命令行工具
在我們剛接觸java學習的時候,大家肯定最先了解的兩個命令就是javac,java,那么除此之外,還有沒有其他的命令可以供我們使用呢?我們進入到安裝jdk的bin目錄,發現還有一系列輔助工具。這些輔助工具用來獲取目標JVM不同方面、不同層次的信息,幫助開發人員很好地解決Java應用程序的一些疑難雜癥。
02-jps:查看正在運行的Java進程
基本情況 jps(Java Process Status )
jps(Java Process Status ) :
顯示指定系統內所有的HotSpot虛擬機進程(查看虛擬機進程信息),可用于查詢正在運行的虛擬機進程。
**說明:**對于本地虛擬機進程來說,進程的本地虛擬機ID與操作系統的進程ID是一致的,是唯一的。
測試
基本語法
jps [options] [hostid]
我們還可以通過追加參數,來打印額外的信息。
options參數
-q:僅僅顯示LVMID (local virtual machine id),即本地虛擬機唯一id。不顯示主類的名稱等
-l:輸出應用程序主類的全類名或如果進程執行的是jar包,則輸出jar完整路徑
-m:輸出虛擬機進程啟動時傳遞給主類main()的參數
-v:列出虛擬機進程啟動時的JVM參數。比如: -Xms20m -Xmx5em是啟動程序指定的jvm參數。
**說明:**以上參數可以綜合使用。
補充:
如果某Java進程關閉了默認開啟的UsePerfData參數(即使用參數
-XX:-UsePerfData),那么jps命令(以及下面介紹的jstat)將無法探知該Java 進程。
hostid參數
RMI注冊表中注冊的主機名。
如果想要遠程監控主機上的java程序,需要安裝jstatd。
對于具有更嚴格的安全實踐的網絡場所而言,可能使用一個自定義的策略文件來顯示對特定的可信主機或網絡的訪問,盡管這種技術容易受到IP地址欺詐攻擊。
如果安全問題無法使用一個定制的策略文件來處理,那么最安全的操作是不運行jstatd服務器,而是在本地使用jstat和jps工具。
03-jstat:查看JVM統計信息 jstat(VM Statistics Monitoring Tool)
基本情況
jstat(VM Statistics Monitoring Tool):用于監視虛擬機各種運行狀態信息的命令行工具。它可以顯示本地或者遠程虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。
在沒有GUI圖形界面,只提供了純文本控制臺環境的服務器上,它將是運行期定位虛擬機性能問題的首選工具。常用于檢測垃圾回收問題以及內存泄漏問題。
官方文檔:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
基本語法
它的基本使用語法為:
jstat -<option>[-t][-h] <vmid> [<interval> [<count>]]
查看命令相關參數:
jstat -h 或 jstat -help
option參數
選項option可以由以下值構成。
類裝載相關的:
. -class:顯示ClassLoader的相關信息:類的裝載、卸載數量、總空間、類裝載所消耗的時間等
垃圾回收相關的:
· -gc:顯示與GC相關的堆信息。包括Eden區、兩個Survivor區、老年代、永久代等的容量、已用空間、GC時間合計等信息。下面有-gc參數信息詳細介紹:往下滑
. -gccapacity:顯示內容與-gc基本相同,但輸出主要關注Java堆各個區域使用到的最大、最小空間。
. -gcutil:顯示內容與-gc基本相同,但輸出主要關注已使用空間占總空間的百分比。
. -gccause:與-gcutil功能一樣,但是會額外輸出導致最后一次或當前正在發生的GC產生的原因。
. -gcnew:顯示新生代Gc狀況
. -gcnewcapacity:顯示內容與-gcnew基本相同,輸出主要關注使用到的最大、最小空間
. -geold:顯示老年代GC狀況
JIT相關的:
-compiler:顯示JIT編譯器編譯過的方法、耗時等信息
-printcompilation:輸出已經被IT編譯的方法
垃圾回收相關 -GC 的參數相關信息解釋
新生代相關
SOC是第一個幸存者區的大小(字節)
S1C是第二個幸存者區的大小(字節)
SOU是第一個幸存者區已使用的大小(字節)
S1U是第二個幸存者區已使用的大小(字節)
EC是Eden空間的大小(字節)
EU是Eden空間已使用大小(字節)
老年代相關
OC是老年代的大小(字節)
OU是老年代已使用的大小(字節)
方法區(元空間)相關
MC是方法區的大小MU是方法區已使用的大小
CCSC是壓縮類空間的大小
CCSU是壓縮類空間已使用的大小
其他
YGC是指從應用程序啟動到采樣時young gc次數
YGCT是指從應用程序啟動到采樣時young gc消耗的時間(秒)
FGC是指從應用程序啟動到采樣時full gc次數
FGCT是指從應用程序啟動到采樣時full gc消耗的時間(秒)
GCT是指從應用程序啟動到采樣時qc的總時間
interval參數
用于指定輸出統計數據的周期,單位為毫秒。即:查詢間隔
count參數
用于指定查詢的總次數
-t參數
可以在輸出信息前加上一個Timestamp列,顯示程序的運行時間。單位:秒
經驗:
可以通過-t來發現
我們可以比較Java進程的啟動時間以及總GC時間(GCT 列),或者兩次測量的間隔時間以及總 GC時間的增量,來得出GC時間占運行時間的比例。
如果該比例超過20%,則說明目前堆的壓力較大;如果該比例超過90%,則說明堆里幾乎沒有可用空間,隨時都可能拋出OOM異常。
-h參數
可以在周期性數據輸出時,輸出多少行數據后輸出一個表頭信息
補充
jstat還可以用來判斷是否出現內存泄漏。
第1步:
在長時間運行的Java程序中,我們可以運行jstat命令連續獲取多行性能數據,并取這幾行數據中OU列(即已占用的老年代內存)的最小值。
第2步:
然后,我們每隔一段較長的時間重復一次上述操作,來獲得多組OU最小值。如果這些值呈上漲趨勢,則說明該Java程序的老年代內存已使用量在不斷上漲,這意味著無法回收的對象在不斷增加,因此很有可能存在內存泄漏。|.
04-jinfo:實時查看和修改JVM配置參數 jinfo(Configuration Info for Java)
基本情況
jinfo(Configuration Info for Java)
查看虛擬機配置參數信息,也可用于調整虛擬機的配置參數。
在很多情況下,Java應用程序不會指定所有的Java虛擬機參數。而此時,開發人員可能不知道某一個具體的Java虛擬機參數的默認值。在這種情況下,可能需要通過查找文檔獲取某個參數的默認值。這個查找過程可能是非常艱難的。但有了jinfo工具,開發人員可以很方便地找到Java虛擬機參數的當前值。
基本語法
它的基本使用語法為:
jinfo [ options ] pid
說明: java進程ID必須要加上
查看
jinfo -sysprops PID
可以查看由System.getProperties()屬性信息
jinfo -flags PID
查看曾經賦過值的一些參數
jinfo -flag具體參數PID
查看某個java進程的具體參數
修改
jinfo不僅可以查看運行時某一個Java虛擬機參數的實際取值,甚至可以在運行時修改部分參數,并使之立即生效。
但是,并非所有參數都支持動態修改。參數只有被標記為manageable的flag可以被實時修改。其實,這個修改能力是極其有限的。
java -XX :+PrintFlagsFinal -version | grep manageable
針對boolean類型
jinfo -flag [+/-]具體參數PID
針對非boolean類型
jinfo -flag具體參數=具體參數
拓展
java -XX: +PrintFlagsInitial
查看所有JVM參數啟動的初始值
java -XX:+PrintFlagsFinal
查看所有JVM參數的最終值
java -XX:+PrintCommandLineFlags
查看那些已經被用戶或者JVM設置過的詳細的XX參數的名稱和值
05-jmap:導出內存映像文件&內存使用情況 jmap(JVM Memory Map)
基本情況
jmap(JVM Memory Map):作用一方面是獲取dump文件(堆轉儲快照文件,二進制文件),它還可以獲取目標Java進程的內存相關信息,包括Java堆各區域的使用情況、堆中對象的統計信息、類加載信息等。
開發人員可以在控制臺中輸入命令“jmap -help”查閱jmap工具的具體使用方式和一些標準選項配置。
官方幫助文檔:
https://docs.oracle.com/en/java/javase/11/tools/jmap.html
基本語法
它的基本使用語法為:
jmap [option] <pid>
jmap [option] <executable <core>
jmap [option] [ server_id@]<remote server IP or hostname>
說明:這些參數和linux下輸入顯示的命令多少會有不同,包括也受jdk版本的影響。
-dump
生成Java堆轉儲快照: dump文件
特別的:-dump:live只保存堆中的存活對象
-heap
輸出整個堆空間的詳細信息,包括GC的使用、堆配置信息,以及內存的使用信息等
-histo
輸出堆中對象的統計信息,包括類、實例數量和合計容量
特別的: -histo:live只統計堆中的存活對象
-permstat
以ClassLoader為統計口徑輸出永久代的內存狀態信息僅linux/solaris平臺有效
-finalizerinfo
顯示在F-Queue中等待Finalizer線程執行finalize方法的對象僅linux/solaris平臺有效
-F
當虛擬機進程對-dump選項沒有任何響應時,可使用此選項強制執行生成dump文件僅linux/solaris平臺有效
-h / -help
jmap工具使用的幫助命令
-J <flag>
傳遞參數給jmap啟動的jvm
使用1:導出內存映像文件dump
一般來說,使用jmap指令生成dump文件的操作算得上是最常用的jmap命令之一,將堆中所有存活對象導出至一個文件之中。
Heap Dump又叫做堆存儲文件,指一個Java進程在某個時間點的內存快照。Heap Dump在觸發內存快照的時候會保存此刻的信息如下:
. All 0bjects
class,fields , primitive values and references.All Classes
classLoader,name , super class,static fields. Garbage collection Roots
objects defined to be reachable by the JVMThread Stacks and Local Variables
The call-stacks of threads at the moment of the snapshot, and per-frameinformation about local objects
說明:
1.通常在寫Heap Dump文件前會觸發一次Full Gc,所以heap dump文件里保存的都是FullGC后留下的對象信息。
2.由于生成dump文件比較耗時,因此大家需要耐心等待,尤其是大內存鏡像生成dump文件則需要耗費更長的時間來完成。
手動的方式
jmap -dump:format=b,file= <filename.hprof> <pid>
jmap -dump:live,format=b,file=<filename.hprof> <pid>
-dump:live只保存堆中的存活對象
自動的方式
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=<filename.hprof>
當程序發生OOM退出系統時,一些瞬時信息都隨著程序的終止而消失,而重現OOM問題往往比較困難或者耗時。此時若能在OOM時,自動導出dump文件就顯得非常迫切。
這里介紹一種比較常用的取得堆快照文件的方法,即使用:
-XX: +HeapDumpOnOutOfMemoryError:在程序發生OOM時,導出應用程序的當前堆快照。
-XX:HeapDumpPath:可以指定堆快照的保存位置。
比如:
-Xmx100m -XX:+HeapDumpOnoutOfMemoryError -XX:HeapDumpPath=D: \m.hprof
使用2:顯示堆內存相關信息
jmap -heap pid
jmap -histo
使用3:其它作用
jmap -permstat pid
查看系統的ClassLoader信息
jmap -finalizerinfo
查看堆積在finalizer隊列中的對象
小結
由于jmap將訪問堆中的所有對象,為了保證在此過程中不被應用線程干擾,jmap需要借助安全點機制,讓所有線程停留在不改變堆中數據的狀態。也就是說,由jmap導出的堆快照必定是安全點位置的。這可能導致基于該堆快照的分析結果存在偏差。
舉個例子,假設在編譯生成的機器碼中,某些對象的生命周期在兩個安全點之間,那么: live選項將無法探知到這些對象。
另外,如果某個線程長時間無法跑到安全點,jmap將一直等下去。與前面講的jstat則不同,垃圾回收器會主動將jstat所需要的摘要數據保存至固定位置之中,而jstat只需直接讀取即可。
06-jhat: JDK自帶堆分析工具jhat(JVM Heap Analysis Tool)了解
基本情況
jhat(JVM Heap Analysis Tool):
Sun JDK提供的jhat命令與jmap命令搭配使用,用于分析jmap生成的heap dump文件((堆轉儲快照)。jhat內置了一個微型的HTTP/HTML服務器,生成dump文件的分析結果后,用戶可以在瀏覽器中查看分析結果(分析虛擬機轉儲快照信息)。
使用了jhat命令,就啟動了一個http服務,端口是7000,即http:/ /localhost:7000/,就可以在瀏覽器里分析。
說明:jhat命令在DK9、JDK10中已經被刪除,官方建議用VisualVM代替。
07-jstack:打印JVM中線程快照 jstack(JVM Stack Trace)
基本情況
jstack(JVM Stack Trace):用于生成虛擬機指定進程當前時刻的線程快照(虛擬機堆棧跟蹤)。線程快照就是當前虛擬機內指定進程的每一條線程正在執行的方法堆棧的集合。
生成線程快照的作用:可用于定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等問題。這些都是導致線程長時間停頓的常見原因。當線程出現停頓時,就可以用jstack顯示各個線程調用的堆棧情況。
官方幫助文檔:
https : / / docs.oracle.com/en/java/javase/11/tools/jstack.html
在thread dump中,要留意下面幾種狀態
·死鎖,Deadlock(重點關注)
·等待資源,Waiting on condition(重點關注)
·等待獲取監視器,Waiting on monitor entry(重點關注)
·阻塞,Blocked(重點關注)
·執行中,Runnable
·暫停,Suspended
·對象等待中,object.wait()或TIMED_WAITING
·停止,Parked
基本語法
jstack option pid
option參數:
-F 當正常輸出的請求不被響應時,強制輸出線程堆棧
-l 除堆棧外,顯示關于鎖的附加信息
-m 如果調用到本地方法的話,可以顯示C/C++的堆棧
-h 幫助操作
java代碼打印stack信息,追蹤當前線程的所有線程,不如jstack
08-jcmd:多功能命令行 jcmd擁有jmap的大部分功能
基本情況
在DK 1.7以后,新增了一個命令行工具jcmd。
它是一個多功能的工具,可以用來實現前面除了jstat之外所有命令的功能。比如:用它來導出堆、內存使用、查看Java進程、導出線程信息、執行GC、JVM運行時間等。
官方幫助文檔:
https: / /docs.oracle.com/en/java/javase/11/tools/jcmd . html
jcmd擁有jmap的大部分功能,并且在Oracle的官方網站上也推薦使用jcmd命令代jmap命令
基本語法
jcmd -l 列出所有的JVM進程
jcmd pid help 針對指定的進程,列出支持的所有命令
jcmd pid <具體命令> 顯示指定進程的指令命令的數據
通過jcmd pid help獲取具體命令
發現此Thread.print具體命令與jstack效果一致
09-jstatd:遠程主機信息收集 了解
之前的指令只涉及到監控本機的Java應用程序,而在這些工具中,一些監控工具也支持對遠程計算機的監控(如jps、jstat)。為了啟用遠程監控,則需要配合使用jstatd 工具。
命令jstatd是一個RMI服務端程序,它的作用相當于代理服務器,建立本地計算機與遠程監控工具的通信。jstatd服務器將本機的Java應用程序信息傳遞到遠程計算機。
總結
以上是生活随笔為你收集整理的JVM学习笔记之-JVM性能监控-JVM监控及诊断工具-命令行方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习笔记之-Activiti7工作流引擎
- 下一篇: JVM学习笔记之-JVM性能监控-JVM