JVM 调优系列之监控工具
轉載自??JVM 調優系列之監控工具
摘要: 項目部署線上之后,我們該如何基于監控工具來快速定位問題....
通過上一篇的jvm垃圾回收知識,我們了解了jvm對內存分配以及垃圾回收是怎么來處理的。理論是指導實踐的工具,有了理論指導,定位問題的時候,知識和經驗是關鍵基礎,數據可以為我們提供依據。
在常見的線上問題時候,我們多數會遇到以下問題:
-
內存泄露
-
某個進程突然cpu飆升
-
線程死鎖
-
響應變慢...等等其他問題。
如果遇到了以上這種問題,在線下可以有各種本地工具支持查看,但到線上了,就沒有這么多的本地調試工具支持,我們該如何基于監控工具來進行定位問題?
我們一般會基于數據收集來定位,而數據的收集離不開監控工具的處理,比如:運行日志、異常堆棧、GC日志、線程快照、堆快照等。經常使用恰當的分析和監控工具可以加快我們的分析數據、定位解決問題的速度。以下我們將會詳細介紹。
?
JVM 常見監控工具&指令
jps:JVM 進程狀況工具
如果不指定hostid就默認為當前主機或服務器。?
命令行參數選項說明如下:
例如:
jstat:JVM 統計信息監控工具
jstat ?是用于見識虛擬機各種運行狀態信息的命令行工具。它可以顯示本地或者遠程虛擬機進程中的類裝載、內存、垃圾收集、jit編譯等運行數據,它是線上定位jvm性能的首選工具。
命令格式:
參數選項:
例如:
查看 gc 情況執行:jstat-gcutil 27777
?
jinfo:Java 配置信息
命令格式:
比如:獲取一些當前進程的jvm運行和啟動信息。
?
jmap:Java 內存映射工具
jmap命令用于生產堆轉存快照。打印出某個java進程(使用pid)內存內的,所有‘對象’的情況(如:產生那些對象,及其數量)。
命令格式:
參數選項:
-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 打印輔助信息?
例如:
使用jmap -heap pid查看進程堆內存使用情況,包括使用的GC算法、堆配置參數和各代中堆內存使用情況:
使用jmap -histo[:live] pid查看堆內存中的對象數目、大小統計直方圖。
?
jhat:JVM 堆快照分析工具
jhat 命令與jamp搭配使用,用來分析map生產的堆快存儲快照。jhat內置了一個微型http/Html服務器,可以在瀏覽器找那個查看。
不過建議盡量不用,既然有dumpt文件,可以從生產環境拉取下來,然后通過本地可視化工具來分析,這樣既減輕了線上服務器壓力,有可以分析的足夠詳盡(比如 MAT/jprofile/visualVm)等。
?
jstack:Java 堆棧跟蹤工具
jstack用于生成java虛擬機當前時刻的線程快照。線程快照是當前java虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等。
命令格式:
參數:
后續的查找耗費最高cpu例子會用到。
?
可視化工具
對jvm監控的常見可視化工具,除了jdk本身提供的Jconsole和visualVm以外,還有第三方提供的jprofilter,perfino,Yourkit,Perf4j,JProbe,MAT等。這些工具都極大的豐富了我們定位以及優化jvm方式。
這些工具的使用,網上有很多教程提供,這里就不再過多介紹了。對于VisualVm來說,比較推薦使用,它除了對jvm的侵入性比較低以外,還是jdk團隊自己開發的,相信以后功能會更加豐富和完善。
jprofilter對于第三方監控工具,提供的功能和可視化最為完善,目前多數ide都支持其插件,對于上線前的調試以及性能調優可以配合使用。
另外對于線上dump的heap信息,應該盡量拉去到線下用于可視化工具來分析,這樣分析更詳細。如果對于一些緊急的問題,必須需要通過線上監控,可以采用?VisualVm的遠程功能來進行,這需要使用tool.jar下的MAT功能。
?
?
應用
在線上有時候某個時刻,可能會出現應用某個時刻突然cpu飆升的問題。對此我們應該熟悉一些指令,快速排查對應代碼。
CPU 飆升
1、找到最耗CPU的進程
指令:
2、找到該進程下最耗費 CPU 的線程
指令:
3、轉換進制
4、過濾指定線程,打印堆棧信息
指令
可以看到是一個上報程序,占用過多cpu了(以上例子只為示例,本身耗費cpu并不高)
?
線程死鎖?
有時候部署場景會有線程死鎖的問題發生,但又不常見。此時我們采用jstack查看下一下。比如說我們現在已經有一個線程死鎖的程序,導致某些操作waiting中。
1、查找 Java 進程 ID
指令
2、查看 Java 進程的線程快照信息
指令
從輸出信息可以看到,有一個線程死鎖發生,并且指出了那行代碼出現的。如此可以快速排查問題。
?
OOM 內存泄露
Java堆內的OOM異常是實際應用中常見的內存溢出異常。一般我們都是先通過內存映射分析工具(比如MAT)對dump出來的堆轉存快照進行分析,確認內存中對象是否出現問題。
當然了出現OOM的原因有很多,并非是堆中申請資源不足一種情況。還有可能是申請太多資源沒有釋放,或者是頻繁頻繁申請,系統資源耗盡。針對這三種情況我需要一一排查。
OOM的三種情況:
1.申請資源(內存)過小,不夠用。
2.申請資源太多,沒有釋放。
3.申請資源過多,資源耗盡。比如:線程過多,線程內存過大等。
1、排查申請申請資源問題
查看新生代,老生代堆內存的分配大小以及使用情況,看是否本身分配過小。
從上述排查,發現程序申請的內存沒有問題。
2、排查 gc
特別是fgc情況下,各個分代內存情況。
3、查找最費內存的對象
上述輸出信息中,最大內存對象才161kb,屬于正常范圍。如果某個對象占用空間很大,比如超過了100Mb,應該著重分析,為何沒有釋放。
?
注意,上述指令:
4、確認資源是否耗盡
pstree 查看進程線程數量
netstat 查看網絡連接數量
或者采用:
ll /proc/${PID}/fd | wc -l ?// 打開的句柄數
ll /proc/${PID}/task | wc -l?(效果等同pstree -p | wc -l) //打開的線程數
以上就是一些常見的jvm命令應用。
?
一種工具的應用并非是萬能鑰匙,包治百病,問題的解決往往是需要多種工具的結合才能更好的定位問題,無論使用何種分析工具,最重要的是熟悉每種工具的優勢和劣勢。這樣才能取長補短,配合使用。
?
?
總結
以上是生活随笔為你收集整理的JVM 调优系列之监控工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果电脑配置在哪里看(苹果电脑 配置)
- 下一篇: axios使用说明