記一次 JVM CPU 使用率飆高問題的排查過程

問題現象

首先,我們一起看看通過 VisualVM 監控到的機器 CPU 使用率圖:
cpu-usage
如上圖所示,在 下午3:45 分之前,CPU 的使用率明顯飆高,最高飆到近 100%,爲什麼會出現這樣的現象呢?

排查過程

Step 1:使用top命令,查詢資源佔用情況:

top

如上圖所示,顯示了服務器當前的資源佔用情況,其中PID5456的進程佔用的資源最多。

在這裏,我們也使用top -p PID命令,查詢指定PID的資源佔用情況:

top-p

Step 2:使用ps -mp PID -o THREAD,tid,time命令,查詢該進程的線程情況:

ps
在這裏,我們也使用ps -mp PID -o THREAD,tid,time | sort -rn命令,將該進程下的線程按資源使用情況倒序展示:
ps-sort

Step 3:使用printf "%x\n" PID命令,將PID轉爲十六進制的TID

printf

在這裏,我們之所以需要將PID轉爲十六進制是因爲在堆棧信息中,PID是以十六進制形式存在的。

Step 4:使用jstack PID | grep TID -A 100命令,查詢堆棧信息:

jstack

如上圖所示,顯示該進程下多個線程均處於TIMED_WAITING狀態。

雖然線程處於WAITING或者TIMED_WAITING狀態都不會消耗 CPU,但是線程頻繁的掛起和喚醒卻會消耗 CPU,而且代價高昂。

而上面之所以會出現 CPU 使用率飆高的情況,則是因爲有人在做壓測。

特別地,在 mock 底層接口的時候,使用了類似TimeUnit.SECONDS.sleep(1)這樣的語句。

至於爲何在 下午3:45 分之後,CPU 的使用率降下來了,則是因爲停止了壓測。


除此之外,我們還可以使用jinfojstat命令來查詢 Java 進程的啓動參數以及 GC 情況:

  • 使用jinfo PID命令,查詢啓動參數:

jinfo
如上圖所示,使用該命令我們主要是爲了查詢啓動參數,如初始化堆大小、垃圾回收器等配置。

  • 使用jstat -gcutil PID 1000命令,查詢 GC 情況:

jstat

如上圖所示,顯示了PID20567的 Java 進程每秒的 GC 情況,其中1000表示 GC 狀態的更新頻率,單位爲毫秒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章