java程序 cpu占用過高分析


         linux終端下用 top命令看到cpu占用超過100%。之所以超過100%。說明cpu是多核。默認top顯示的是cpu加起來的使用率,運行top后按大鍵盤1看看,可以顯示每個cpu的使用率,top里顯示的是把所有使用率加起來。如果是4核cpu占用率最高可達400%。

 

java進程占用CPU過高常見的兩種情況及分析定位

https://blog.csdn.net/dingjianmin/article/details/85705812

在linux中的定位方法
4.1.找到CPU占用高的進程號 如:使用top命令查看(可以使用其它方法,只要找到對應的進程號即可)

注:圖中第一列PID為進程號;

4.2、根據進程號找到CPU占用高的線程
如:使用命令top -H -p (其中要換成第一步找到的進程號)

 

top連接參數說明

-H :Threads-mode operation
Instructs top to display individual threads. Without this command-line option a summation of all threads in each process is shown. Later this can be changed with the `H' interactive command.
 
-p :Monitor-PIDs mode as: -pN1 -pN2 ... or -pN1,N2,N3 ...
Monitor only processes with specified process IDs. This option can be given up to 20 times, or you can provide a comma delimited list with up to 20 pids. Co-mingling both approaches is permitted.
1
2
查看某個進程內部線程占用情況分析:
top -H -p 18605
 

 

注:圖中第一列PID此時為線程號;

4.3.導出java進程執行堆棧,並找到對應的線程
使用jstack > jstack_xxx.txt (其中要換成第一步找到的進程號)
從第二步中的PID中找出一個CPU占用高的線程號,把它轉成16進制,比如3261轉成CBD
從導出的堆棧信息里找到nid為cbd的線程堆棧

 

https://www.cnblogs.com/wuchanming/p/7766994.html

 


4.4:從堆棧里找到對應的代碼執行類和方法
若代碼為業務代碼,則需要具體分析代碼,找出代碼中死循環或接近死循環的地方,並修正;定位結束;

若堆棧信息為gc線程(類似下圖),則需要進行下一步

4.5:dump出java進程的堆對象使用情況
使用jmap -histo > jmap_xxx.txt


找出量比較大的、且跟業務有關的對象,找到這些對象創建的地方進行分析;一般需要持續創建大量的對象,使得內存不夠用時,才會頻繁觸發gc進行回收,gc回收時jvm有停頓,CPU也占用很高。

線程之間的切換,是很耗費性能的,所以帶來CPU飆升.
新生代設置過小,也會頻繁觸發gc。有大對象始終根節點路徑可達,無法釋放,jvm在瘋狂的Full GC。
---------------------
 

 


一篇文章:

https://blog.csdn.net/whupanyinghua/article/details/51649819

 

簡單記錄下對這個問題的跟蹤

首先當然要看下具體是java中哪個線程一直在占用cpu時間哈(說明下, java進程號是 26178)
1.根據java進程ID進行CPU占用排查  ps -mp 26178 -o THREAD,tid,time | sort -rn | more  (sort -rn 以數值的方式進行逆序排列)

 


2.根據1中查找到的CPU最高的排序中的結果,找出幾個占用cpu時間比較高的TID,比如這里的26217 26182 26183
將進程ID轉換為16進制,printf "%x\n" 26217

3.再使用jstack命名查詢是哪個線程
TID十進制-》十六進制
26217 -》 6669
26182 -》 6646
26183 -》 6647
拿到線程ID的16進制之后,就可以從jstack中查找具體是對應的線程
jstack 26178 |grep 6669 -A 30

可以發現,幾個占用大量cpu時間的線程都是GC相關。

(grep -A:

Context control:
-B, --before-context=NUM print NUM lines of leading context
-A, --after-context=NUM print NUM lines of trailing context

找出filename中帶有keyword的行,輸出中除顯示該行外,還顯示之后的x行。其中,數字可以變。

 


-C, --context=NUM print NUM lines of output context

 

 

4.再次確認gc信息,查看gc time等信息,jstat -gcutil 26178 1000 100

 

可以看到s0、s1、eden、old、metaspace都已經爆了,並且FGC次數一直在增加,但是卻沒有回收到任何空間,導致FGC一直在跑,進入循環,應該是程序存在內存泄露咯。(gc有日志,后續有空再出一篇簡單分析gc日志的blog)

5.jmap -histo:live 26178 | more  簡單查看對象的大小數目

6.dump內存,使用工具分析內存鏡像,jmap -dump:live,format=b,file=problem.bin 26178

7.使用MAT(Memory Analyzer tool)進行數據分析,注意,如果步驟6中dump出來文件過大,需要設置MAT配置文件(MemoryAnalyzer.ini)的xmx參數的大小。
---------------------  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM