jstatgc佔用cpu,jstat gc

本文目錄一覽:

記一次線上機器CPU飆高的排查過程

        公司如今把小貸機器都整理回收了,訪問量不大,基本都是用戶來查看賬戶進行還款操作。

        現在情況是,我們把很多服務都放在了一台伺服器上,那天線上環境改了auth的salt,本地這邊是寫死的,自動上線已經關閉了通道,沒轍,手動替包手動上線,結果沒多久運維就喊了,表示cpu飆高到300%。

        難得的機會,先用top找出cpu佔用最多進程

如果想細看進程信息可以使用ll proc

其實運行完這裡的時候,我比較吃驚的是,真正佔CPU的並不是部署的幾個服務,而是resin容器本身,飈到了99%,從這個角度來講,其實大部分性能問題都是垃圾回收的鍋。

然後利用ps查看到的進程pid找cpu最高線程

然後拿著線程tid在jstack找,結果在裡面找不到,然後上網查JAVA線程無法在jstack里找到的原因

以上大概意思是沒找到線程的跟蹤棧有三種情況,就是線程啟動前的預啟動,以及線程退出後的cleanup,第三種就是,利用JVM TI agent運行的線程,這個線程是用來跑本地code的。

******這裡面都提到了JVM TI技術,這個技術主要是用來提供虛擬機調用本地方法的介面,可以獲取jvm運行情況和提供本地方法的後門一樣的介面工具,一些調試和診斷工具都是基於JVM TI來實現的,很多JVM都有自己的TI實現。

當然,這個Stack Over Flow的答案針對的Java線程,我所知道的是,如果導致我們CPU飆高的並不是java線程,那麼jstack -F就打不出來。

而這個jstack -m模式,在官方文檔里是說,可以列印出所有Java線程和native frames的所有線程。其實到這裡是不是隱隱感覺到什麼了~~沒錯,最後真的是垃圾回收的鍋。

然後jdk8利用jstack -m找到了,發現裡面使用的方法是CMS垃圾回收器的方法

講真,平時只負責上下線,JVM配置只要不出問題很少留意,這個年代了,還在使用CMS嗎?嗯,jmap看了下,是CMS。而佔用大多CPU也是CMS的特性之一:最小化GC中斷,付出的代價便是高CPU負荷。

既然定位到了垃圾回收,那就接著排查垃圾回收吧,pid是18637

就去jstat -gc 18637 5000

jstat -gcold 18637

jstat -gcoldcapacity 18637

發現full gc非常頻繁(每五秒輸出,發現觸發fullGC13次)

(復盤這次的排查問題,發現圖片保存少之又少。。)

如此頻繁,順帶gccause一下看看最近一次回收的原因

結果長這樣

從這個結果來看最近一次是Metadata的GC,而觸發原因是因為達到了閾值。再細看當前元空間使用率已經接近98%。

到這裡不能等了,找運維拿來了jvm參數,有三個參數很亮眼

老年代的配置屬於默認配置,占整個堆內存的2/3,CMS回收要達到80%才會觸發,我們還沒有達到這個值。

那麼根據圖1中的顯示,metaspace我們已經達到了閾值。

這種情況產生也沒毛病,想想一台機器部署了5個web服務和5個微服務的場景吧,雖然沒什麼人訪問,但載入的class信息也足夠多了。

主要就是metadata的配置,而有關metadata的配置並沒有oracle的官方指導,官方指導上的意思是說metaspace的配置,主要是避免首次啟動時對載入的類信息做回收,取決於應用本身,夠用就行了,不要太頻繁觸發full gc就好

其實調大這metaspace的配置能夠大概解決問題,但是最終我選擇了切換為G1垃圾回收。

官方文檔是這樣寫的

        首先戳我的點的主要原因是g1最終的目的是要取代cms垃圾回收器,它的回收範圍是整個堆,緊跟潮流總不會錯的。其次g1取代cms的情況官方也建議了以下幾點:

1. 一個是要管理的堆內存大於6g

2. 一個是服務已使用的堆內存超過了50%

3. 一個是對象分配率過高或對象從新生代晉陞到老年代速率過快(這裡我查了一下資料,意思是對象分配率過高的話其實會導致Minor GC頻繁,而這種情況會使對象更快地晉陞到老年代,而老年代如果過快地被填充,又會觸發FullGC。從設計角度來講,之所以分代回收,是為了應對對象存活時間而使用不同的回收策略,老年代可不是為了頻繁回收而產生的)

4. 垃圾回收導致服務中斷時長超過0.5-1s。

這種時候官方就建議把cms換成g1了。

        最終cpu驟降,從99%降至一般運行狀態下的2%左右。好了。就這樣吧,雖然不希望線上出現這種問題,但一旦出問題了,搞一遍還蠻帶感的。期待下一次的摸排:DDDDD

後記:

        最近在復盤這次垃圾回收,因為這次jvm排查的經歷讓我對垃圾回收機制和分代回收這一塊加深了印象。復盤的時候發現自己思考地還欠缺深入。這次的問題有兩個地方值得深思,一個是為什麼metaspace會超?如果正常進行GC,為何會超出閾值?其次是沒有調大metaspace的前提下,換成G1為什麼就沒有再頻繁FullGC過?

        為什麼metaspace會超,我經過比對當時留下CMS的jstat數據和G1當前的數據,發現新生代CMS劃分區域非常大,是現在G1的十倍。G1是不建議設定新老年代比例的,這樣它就可以動態調整新老年代比例,達到最優實踐。首先說明metaspace是存儲類描述信息的,當堆上分配了對象,就會關聯到metaspace裡面的類信息,如果堆上的對象不回收,那麼metaspace裡面的類信息也不會回收。

        在配置cms時,我們會設置新生代老年代比例,新生代空間是固定的,如果新生代的空間比較大,回收間隔時間長,那就會導致metaspace里的class信息無法被釋放,最終導致未進行youngGC而率先因為metaspace超了跑了FullGC。但G1的新生代空間是根據使用情況動態分配的,它的演算法會去回收最有回收價值的region。

        就這次修改參數而言,使用G1比CMS時間短很多,就已經執行了717次youngGC,而CMS用了那麼久,才52次,側面也能佐證這個猜測的正確性,解釋了為何在相同metaspace的配置下,G1沒有產生頻繁FullGC的原因:新生代對象回收加快,metaspace空間得到了儘快釋放,沒有達到閾值,於是不會觸發FullGC。

參考文獻:

*

*

*

*

*

jvm 性能調優工具之 jstat 命令詳解

Jstat名稱:Java Virtual Machine statistics monitoring tool

功能描述:

Jstat是JDK自帶的一個輕量級小工具。它位於java的bin目錄下,主要利用JVM內建的指令對Java應用程序的資源和性能進行實時的命令行的監控,包括了對Heap size和垃圾回收狀況的監控。

命令用法:jstat [-命令選項] [vmid] [間隔時間/毫秒] [查詢次數]

注意:使用的jdk版本是jdk8。

C:\Users\Administratorjstat -helpUsage: jstat -help|-options jstat -option [-t] [-hlines] vmid [interval [count]] Definitions: option An option reported by the -options option vmid Virtual Machine Identifier. A vmid takes the following form: lvmid[@hostname[:port]] Where lvmid is the local vm identifier for the target Java virtual machine, typically a process id; hostname is the name of the host running the target Java virtual machine; and port is the port number for the rmiregistry on the target host. See the jvmstat documentation for a more complete description of the Virtual Machine Identifier. lines Number of samples between header lines. interval Sampling interval. The following forms are allowed: n[“ms”|”s”] Where n is an integer and the suffix specifies the units as milliseconds(“ms”) or seconds(“s”). The default units are “ms”. count Number of samples to take before terminating. -Jflag Pass flag directly to the runtime system.

option:參數選項

-t:可以在列印的列加上Timestamp列,用於顯示系統運行的時間

-h:可以在周期性數據輸出的時候,指定輸出多少行以後輸出一次表頭

vmid:Virtual Machine ID( 進程的 pid)

interval:執行每次的間隔時間,單位為毫秒

count:用於指定輸出多少次記錄,預設則會一直列印

option 可以從下面參數中選擇

jstat -options

-class 用於查看類載入情況的統計

-compiler 用於查看HotSpot中即時編譯器編譯情況的統計

-gc 用於查看JVM中堆的垃圾收集情況的統計

-gccapacity 用於查看新生代、老生代及持久代的存儲容量情況

-gcmetacapacity 顯示metaspace的大小

-gcnew 用於查看新生代垃圾收集的情況

-gcnewcapacity 用於查看新生代存儲容量的情況

-gcold 用於查看老生代及持久代垃圾收集的情況

-gcoldcapacity 用於查看老生代的容量

-gcutil 顯示垃圾收集信息

-gccause 顯示垃圾回收的相關信息(通-gcutil),同時顯示最後一次僅當前正在發生的垃圾收集的原因

-printcompilation 輸出JIT編譯的方法信息

示例:

1.-class 類載入統計

[root@hadoop ~]# jps #先通過jps獲取到java進程號(這裡是一個zookeeper進程)3346 QuorumPeerMain7063 Jps[root@hadoop ~]# jstat -class 3346 #統計JVM中載入的類的數量與sizeLoaded Bytes Unloaded Bytes Time 1527 2842.7 0 0.0 1.02

Loaded:載入類的數量

Bytes:載入類的size,單位為Byte

Unloaded:卸載類的數目

Bytes:卸載類的size,單位為Byte

Time:載入與卸載類花費的時間

2.-compiler 編譯統計

[root@hadoop ~]# jstat -compiler 3346 #用於查看HotSpot中即時編譯器編譯情況的統計Compiled Failed Invalid Time FailedType FailedMethod 404 0 0 0.19 0

Compiled:編譯任務執行數量

Failed:編譯任務執行失敗數量

Invalid:編譯任務執行失效數量

Time:編譯任務消耗時間

FailedType:最後一個編譯失敗任務的類型

FailedMethod:最後一個編譯失敗任務所在的類及方法

3.-gc 垃圾回收統計

[root@hadoop ~]# jstat -gc 3346 #用於查看JVM中堆的垃圾收集情況的統計 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 128.0 128.0 0.0 128.0 1024.0 919.8 15104.0 2042.4 8448.0 8130.4 1024.0 996.0 7 0.019 0 0.000 0.019

S0C:年輕代中第一個survivor(倖存區)的容量 (位元組)

S1C:年輕代中第二個survivor(倖存區)的容量 (位元組)

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

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

EC:年輕代中Eden(伊甸園)的容量 (位元組)

EU:年輕代中Eden(伊甸園)目前已使用空間 (位元組)

OC:Old代的容量 (位元組)

OU:Old代目前已使用空間 (位元組)

MC:metaspace(元空間)的容量 (位元組)

MU:metaspace(元空間)目前已使用空間 (位元組)

CCSC:當前壓縮類空間的容量 (位元組)

CCSU:當前壓縮類空間目前已使用空間 (位元組)

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

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

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

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

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

4.-gccapacity 堆內存統計

[root@hadoop ~]# jstat -gccapacity 3346 #用於查看新生代、老生代及持久代的存儲容量情況 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0[root@hadoop ~]# jstat -gccapacity -h5 3346 1000 #-h5:每5行顯示一次表頭 1000:每1秒鐘顯示一次,單位為毫秒 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0

NGCMN:年輕代(young)中初始化(最小)的大小(位元組)

NGCMX:年輕代(young)的最大容量 (位元組)

NGC:年輕代(young)中當前的容量 (位元組)

S0C:年輕代中第一個survivor(倖存區)的容量 (位元組)

S1C:年輕代中第二個survivor(倖存區)的容量 (位元組)

EC:年輕代中Eden(伊甸園)的容量 (位元組)

OGCMN:old代中初始化(最小)的大小 (位元組)

OGCMX:old代的最大容量(位元組)

OGC:old代當前新生成的容量 (位元組)

OC:Old代的容量 (位元組)

MCMN:metaspace(元空間)中初始化(最小)的大小 (位元組)

MCMX:metaspace(元空間)的最大容量 (位元組)

MC:metaspace(元空間)當前新生成的容量 (位元組)

CCSMN:最小壓縮類空間大小

CCSMX:最大壓縮類空間大小

CCSC:當前壓縮類空間大小

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

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

5.-gcmetacapacity 元數據空間統計

[root@hadoop ~]# jstat -gcmetacapacity 3346 #顯示元數據空間的大小MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 8 0 0.000 0.020

MCMN:最小元數據容量

MCMX:最大元數據容量

MC:當前元數據空間大小

CCSMN:最小壓縮類空間大小

CCSMX:最大壓縮類空間大小

CCSC:當前壓縮類空間大小

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

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

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

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

6.-gcnew 新生代垃圾回收統計

[root@hadoop ~]# jstat -gcnew 3346 #用於查看新生代垃圾收集的情況S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT128.0 128.0 67.8 0.0 1 15 64.0 1024.0 362.2 8 0.020

S0C:年輕代中第一個survivor(倖存區)的容量 (位元組)

S1C:年輕代中第二個survivor(倖存區)的容量 (位元組)

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

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

TT:持有次數限制

MTT:最大持有次數限制

DSS:期望的倖存區大小

EC:年輕代中Eden(伊甸園)的容量 (位元組)

EU:年輕代中Eden(伊甸園)目前已使用空間 (位元組)

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

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

7.-gcnewcapacity 新生代內存統計

[root@hadoop ~]# jstat -gcnewcapacity 3346 #用於查看新生代存儲容量的情況NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC1280.0 83264.0 1280.0 8320.0 128.0 8320.0 128.0 66624.0 1024.0 8 0

NGCMN:年輕代(young)中初始化(最小)的大小(位元組)

NGCMX:年輕代(young)的最大容量 (位元組)

NGC:年輕代(young)中當前的容量 (位元組)

S0CMX:年輕代中第一個survivor(倖存區)的最大容量 (位元組)

S0C:年輕代中第一個survivor(倖存區)的容量 (位元組)

S1CMX:年輕代中第二個survivor(倖存區)的最大容量 (位元組)

S1C:年輕代中第二個survivor(倖存區)的容量 (位元組)

ECMX:年輕代中Eden(伊甸園)的最大容量 (位元組)

EC:年輕代中Eden(伊甸園)的容量 (位元組)

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

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

8.-gcold 老年代垃圾回收統計

[root@hadoop ~]# jstat -gcold 3346 #用於查看老年代及持久代垃圾收集的情況MC MU CCSC CCSU OC OU YGC FGC FGCT GCT8448.0 8227.5 1024.0 1003.7 15104.0 2102.2 8 0 0.000 0.020 

MC:metaspace(元空間)的容量 (位元組)

MU:metaspace(元空間)目前已使用空間 (位元組)

CCSC:壓縮類空間大小

CCSU:壓縮類空間使用大小

OC:Old代的容量 (位元組)

OU:Old代目前已使用空間 (位元組)

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

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

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

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

9.-gcoldcapacity 老年代內存統計

[root@hadoop ~]# jstat -gcoldcapacity 3346 #用於查看老年代的容量OGCMN OGCMX OGC OC YGC FGC FGCT GCT15104.0 166592.0 15104.0 15104.0 8 0 0.000 0.020

OGCMN:old代中初始化(最小)的大小 (位元組)OGCMX:old代的最大容量(位元組)OGC:old代當前新生成的容量 (位元組)OC:Old代的容量 (位元組)YGC:從應用程序啟動到採樣時年輕代中gc次數FGC:從應用程序啟動到採樣時old代(全gc)gc次數FGCT:從應用程序啟動到採樣時old代(全gc)gc所用時間(s)GCT:從應用程序啟動到採樣時gc用的總時間(s) 在此我向大家推薦一個架構學習交流圈。交流學習指導偽鑫:1253431195(裡面有大量的面試題及答案)裡面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高並發、高性能、分散式、微服務架構的原理,JVM性能優化、分散式架構等這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

10.-gcutil 垃圾回收統計

[root@hadoop ~]# jstat -gcutil 3346 #顯示垃圾收集信息S0 S1 E O M CCS YGC YGCT FGC FGCT GCT52.97 0.00 42.10 13.92 97.39 98.02 8 0.020 0 0.000 0.020 

S0:年輕代中第一個survivor(倖存區)已使用的占當前容量百分比

S1:年輕代中第二個survivor(倖存區)已使用的占當前容量百分比

E:年輕代中Eden(伊甸園)已使用的占當前容量百分比

O:old代已使用的占當前容量百分比

M:元數據區已使用的占當前容量百分比

CCS:壓縮類空間已使用的占當前容量百分比

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

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

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

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

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

11.-gccause

[root@hadoop ~]# jstat -gccause 3346 #顯示垃圾回收的相關信息(通-gcutil),同時顯示最後一次或當前正在發生的垃圾回收的誘因S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC52.97 0.00 46.09 13.92 97.39 98.02 8 0.020 0 0.000 0.020 Allocation Failure No GC

LGCC:最後一次GC原因

GCC:當前GC原因(No GC 為當前沒有執行GC)

12.-printcompilation JVM編譯方法統計

[root@hadoop ~]# jstat -printcompilation 3346 #輸出JIT編譯的方法信息Compiled Size Type Method421 60 1 sun/nio/ch/Util$2 clear

Compiled:編譯任務的數目

Size:方法生成的位元組碼的大小

Type:編譯類型

Method:類名和方法名用來標識編譯的方法。類名使用/做為一個命名空間分隔符。方法名是給定類中的方法。上述格式是由-XX:+PrintComplation選項進行設置的

遠程監控

與jps一樣,jstat也支持遠程監控,同樣也需要開啟安全授權,方法參照jps。

C:\Users\Administratorjps 192.168.146.1283346 QuorumPeerMain3475 JstatdC:\Users\Administratorjstat -gcutil 3346@192.168.146.128 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 52.97 0.00 65.15 13.92 97.39 98.02 8 0.020 0 0.000 0.020

cpu飆升怎麼排查

一、引子

對於互聯網公司,線上CPU飆升的問題很常見(例如某個活動開始,流量突然飆升時),按照本文的步驟排查,基本1分鐘即可搞定!特此整理排查方法一篇,供大家參考討論提高。

二、問題復現

線上系統突然運行緩慢,CPU飆升,甚至到100%,以及Full GC次數過多,接著就是各種報警:例如介面超時報警等。此時急需快速線上排查問題。

三、問題排查

不管什麼問題,既然是CPU飆升,肯定是查一下耗CPU的線程,然後看看GC。

3.1 核心排查步驟

1.執行「top」命令:查看所有進程占系統CPU的排序。極大可能排第一個的就是咱們的java進程(COMMAND列)。PID那一列就是進程號。

2.執行「top -Hp 進程號」命令:查看java進程下的所有線程佔CPU的情況。

3.執行「printf “%x\n 10″命令 :後續查看線程堆棧信息展示的都是十六進位,為了找到咱們的線程堆棧信息,咱們需要把線程號轉成16進位。例如,printf “%x\n 10-》列印:a,那麼在jstack中線程號就是0xa.

4.執行 「jstack 進程號 | grep 線程ID」 查找某進程下-》線程ID(jstack堆棧信息中的nid)=0xa的線程堆棧信息。如果「”VM Thread” os_prio=0 tid=0x00007f871806e000 nid=0xa runnable」,第一個雙引號圈起來的就是線程名,如果是「VM Thread」這就是虛擬機GC回收線程了

5.執行「jstat -gcutil 進程號 統計間隔毫秒 統計次數(預設代表一致統計)」,查看某進程GC持續變化情況,如果發現返回中FGC很大且一直增大-》確認Full GC! 也可以使用「jmap -heap 進程ID」查看一下進程的堆內從是不是要溢出了,特別是老年代內從使用情況一般是達到閾值(具體看垃圾回收器和啟動時配置的閾值)就會進程Full GC。

6.執行「jmap -dump:format=b,file=filename 進程ID」,導出某進程下內存heap輸出到文件中。可以通過eclipse的mat工具查看內存中有哪些對象比較多。

3.2 原因分析

1.內存消耗過大,導致Full GC次數過多

執行步驟1-5:

多個線程的CPU都超過了100%,通過jstack命令可以看到這些線程主要是垃圾回收線程-》上一節步驟2

通過jstat命令監控GC情況,可以看到Full GC次數非常多,並且次數在不斷增加。–》上一節步驟5

確定是Full GC,接下來找到具體原因:

生成大量的對象,導致內存溢出-》執行步驟6,查看具體內存對象佔用情況。

內存佔用不高,但是Full GC次數還是比較多,此時可能是代碼中手動調用 System.gc()導致GC次數過多,這可以通過添加 -XX:+DisableExplicitGC來禁用JVM對顯示GC的響應。

2.代碼中有大量消耗CPU的操作,導致CPU過高,系統運行緩慢;

執行步驟1-4:在步驟4jstack,可直接定位到代碼行。例如某些複雜演算法,甚至演算法BUG,無限循環遞歸等等。

3.由於鎖使用不當,導致死鎖。

執行步驟1-4:如果有死鎖,會直接提示。關鍵字:deadlock.步驟四,會列印出業務死鎖的位置。

造成死鎖的原因:最典型的就是2個線程互相等待對方持有的鎖。

4.隨機出現大量線程訪問介面緩慢。

代碼某個位置有阻塞性的操作,導致該功能調用整體比較耗時,但出現是比較隨機的;平時消耗的CPU不多,而且佔用的內存也不高。

思路:

首先找到該介面,通過壓測工具不斷加大訪問力度,大量線程將阻塞於該阻塞點。

使用jstat命令會影響java進程嗎

使用jstat命令會影響java進程

JDK自帶VM分析工具jps,jstat,jmap,jconsole

關鍵字: jdk自帶vm分析工具jps,jstat,jmap,jconsole

一、概述

SUN 的JDK中的幾個工具,非常好用。秉承著有免費,不用商用的原則。以下簡單介紹一下這幾種工具。(註:本文章下的所有工具都存在JDK5.0以上版本的工具集里,同javac一樣,不須特意安裝) 。

我一共找到以下四個工具:重點看看jconsole和jmap。

jps

:與unix上的ps類似,用來顯示本地的java進程,可以查看本地運行著幾個java程序,並顯示他們的進程號。

jstat

:一個極強的監視VM內存工具。可以用來監視VM內存內的各種堆和非堆的大小及其內存使用量。

jmap

:列印出某個java進程(使用pid)內存內的所有『對象』的情況(如:產生那些對象,及其數量)。

jconsole

:一個java GUI監視工具,可以以圖表化的形式顯示各種數據。並可通過遠程連接監視遠程的伺服器VM。

二、 使用介紹:

1、jps :我想很多人都是用過unix系統里的ps命令,這個命令主要是用來顯示當前系統的進程情況,有哪些進程,及其 id。 jps 也是一樣,它的作用是顯示當前系統的java進程情況,及其id號。我們可以通過它來查看我們到底啟動了幾個java進程(因為每一個java程序都會獨佔一個java虛擬機實例),和他們的進程號(為下面幾個程序做準備),並可通過opt來查看這些進程的詳細啟動參數。

使用方法:在當前命令行下打 jps(需要JAVA_HOME,沒有的話,到改程序的目錄下打) 。

可惜沒有linux下的ps好用,名稱不好用。但是在第四個工具jconsole的界面裡面會有具體JAR包的名稱。

2、jstat :對VM內存使用量進行監控。

jstat工具特彆強大,有眾多的可選項,詳細查看堆內各個部分的使用量,以及載入類的數量。使用時,需加上查看進程的進程id,和所選參數。以下詳細介紹各個參數的意義。

jstat -class pid:顯示載入class的數量,及所佔空間等信息。

jstat -compiler pid:顯示VM實時編譯的數量等信息。

jstat -gc pid:可以顯示gc的信息,查看gc的次數,及時間。其中最後五項,分別是young gc的次數,young gc的時間,full gc的次數,full gc的時間,gc的總時間。

jstat -gccapacity:可以顯示,VM內存中三代(young,old,perm)對象的使用和佔用大小,如:PGCMN顯示的是最小perm的內存使用量,PGCMX顯示的是perm的內存最大使用量,PGC是當前新生成的perm內存佔用量,PC是但前perm內存佔用量。其他的可以根據這個類推, OC是old內純的佔用量。

jstat -gcnew pid:new對象的信息。

jstat -gcnewcapacity pid:new對象的信息及其佔用量。

jstat -gcold pid:old對象的信息。

jstat -gcoldcapacity pid:old對象的信息及其佔用量。

jstat -gcpermcapacity pid: perm對象的信息及其佔用量。

jstat -util pid:統計gc信息統計。

jstat -printcompilation pid:當前VM執行的信息。

除了以上一個參數外,還可以同時加上 兩個數字,如:jstat -printcompilation 3024 250 6是每250毫秒列印一次,一共列印6次,還可以加上-h3每三行顯示一下標題。

3、jmap 是一個可以輸出所有內存中對象的工具,甚至可以將VM 中的heap,以二進位輸出成文本。使用方法 jmap -histo pid。如果連用 SHELL jmap -histo pida.log可以將其保存到文本中去(windows下也可以使用),在一段時間後,使用文本對比工具,可以對比出GC回收了哪些對象。 jmap -dump:format=b,file=f1 3024可以將3024進程的內存heap輸出出來到f1文件里。

4、jconsole 是一個用java寫的GUI程序,用來監控VM,並可監控遠程的VM,非常易用,而且功能非常強。由於是GUI程序,這裡就不詳細介紹了,不會的地方可以參考SUN的官方文檔。

使用方法:命令行里打 jconsole,選則進程就可以了。

友好提示:windows查看進程號,由於任務管理器默認的情況下是不顯示進程id號的,所以可以通過如下方法加上。ctrl+alt+del打開任務管理器,選擇『進程』選項卡,點『查看』-”選擇列”-加上”PID”,就可以了。當然還有其他很好的選項。

Linux使用jstat命令查看jvm的GC情況

Linux 使用jstat命令查看jvm的GC情況

命令格式

jstat命令命令格式:

jstat [Options] vmid[interval] [count]

參數說明:

Options,選項,我們一般使用 -gcutil 查看gc情況

vmid

,VM的進程號,即當前運行的java進程號

interval

,間隔時間,單位為秒或者毫秒

count

,列印次數,如果預設則列印無數次

示例說明

示例

通常運行命令如下:

jstat -gc 12538 5000

即會每5秒一次顯示進程號為12538的java進成的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)

NGCMN

:年輕代(young)中初始化(最小)的大小 (位元組)

NGCMX

:年輕代(young)的最大容量 (位元組)

NGC

:年輕代(young)中當前的容量 (位元組)

OGCMN

:old代中初始化(最小)的大小 (位元組)

OGCMX

:old代的最大容量 (位元組)

OGC

:old代當前新生成的容量 (位元組)

PGCMN

:perm代中初始化(最小)的大小 (位元組)

PGCMX

:perm代的最大容量 (位元組)

PGC

:perm代當前新生成的容量 (位元組)

S0

:年輕代中第一個survivor(倖存區)已使用的占當前容量百分比

S1

:年輕代中第二個survivor(倖存區)已使用的占當前容量百分比

E

:年輕代中Eden(伊甸園)已使用的占當前容量百分比

O

:old代已使用的占當前容量百分比

P

:perm代已使用的占當前容量百分比

S0CMX

:年輕代中第一個survivor(倖存區)的最大容量 (位元組)

S1CMX

:年輕代中第二個survivor(倖存區)的最大容量 (位元組)

ECMX

:年輕代中Eden(伊甸園)的最大容量 (位元組)

DSS

:當前需要survivor(倖存區)的容量 (位元組)(Eden區已滿)

TT

: 持有次數限制

MTT

: 最大持有次數限制

原創文章,作者:ULNZ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/134772.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ULNZ的頭像ULNZ
上一篇 2024-10-04 00:08
下一篇 2024-10-04 00:08

相關推薦

  • CPU爆滿怎麼解決 Java為中心

    在Java編程中,難免會遇到CPU佔用過高的情況,接下來從多個方面介紹如何解決CPU爆滿問題。 一、優化代碼 1、減少循環次數。循環體內不要放太多邏輯判斷和計算,可以把計算提取出來…

    編程 2025-04-29
  • CPU是否可以直接執行硬碟中的程序?

    CPU是否可以直接執行硬碟中的程序?這是一個常見的問題,我們將從多個方面對這個問題進行探討。 一、計算機啟動過程 在回答這個問題之前,先要了解計算機的啟動過程。計算機啟動時,BIO…

    編程 2025-04-27
  • CPU Load Average

    CPU Load Average 是計算機系統性能指標之一,它是一個虛擬的概念,通常在 Linux 和 Unix 系統中使用。它用于衡量處理器在一段時間內的工作負載,可以通過該指標…

    編程 2025-04-25
  • 深入了解Young GC

    Young GC是Java虛擬機GC的一部分,專門負責垃圾回收。在JVM內存管理中,垃圾回收是一個非常重要的問題,而你的應用的性能也是與之互為影響的。在這篇文章中,我們將會從以下幾…

    編程 2025-04-23
  • k8scpu: Kubernetes資源調度中的CPU管理

    在Kubernetes中,我們可以使用k8scpu來管理CPU資源。這個工具可以幫助我們確保每個容器都有足夠的CPU資源來運行應用程序,同時避免浪費資源。本文將從多個方面對k8sc…

    編程 2025-04-23
  • Idea CPU佔用高的分析與優化

    一、錯誤的配置和插件導致CPU過高 1、如果你的Idea設置了過多且不必要的插件,那麼就會導致CPU佔用較高。Idea是一個非常強大的IDE,但它也非常重量級。對於一些基本的重構和…

    編程 2025-04-23
  • CentOS查看CPU的方法

    CentOS作為一種流行的Linux操作系統,是很多企業和個人使用的首選之一。對於開發和維護任務,可能需要查看CPU的狀態和性能,並據此進行優化和調整。下面將從幾個不同的角度介紹C…

    編程 2025-04-23
  • GC抖動的時候還要繼續么

    一、什麼是GC抖動 GC(垃圾回收)抖動是指當應用程序的垃圾回收器不斷進行垃圾回收操作,卻無法釋放足夠的內存空間,導致程序的性能出現明顯下降。 二、引起GC抖動的因素 由於Java…

    編程 2025-04-12
  • CPU寄存器的詳細闡述

    一、寄存器的定義 寄存器是CPU內存儲器的一部分,也是CPU用來暫存指令、數據和地址的地方。寄存器的大小往往是固定的,因為它們是硬體實現的。寄存器的數量和大小以及其具體用途因CPU…

    編程 2025-04-12
  • 鯤鵬:一款強大的CPU

    一、 總覽 鯤鵬是由華為推出的一款處理器晶元,它是當今世界上最強大的CPU之一。它採用ARM64架構,並集成了多種技術,如圖形處理、人工智慧等。鯤鵬是一款運行速度快、耗能低、集成度…

    編程 2025-04-12

發表回復

登錄後才能評論