java程序——CPU過高100%及內存泄露排查


CPU過高

這類問題可以使用 top 命令觀察一些,CPU 是不是都被 Java 程序占用了。比如下面這個截圖:

服務器的 CPU 大多都被 Java 占用了。這正是我們之前生產上 CPU 過高的一個截圖。

服務其CPU 還能超過 100%原因

在 Linux 上,多核 CPU 就會超過 100%。top 命令顯示的是你的程序占用的 cpu 的總數,也就是說如果你是 4 核 cpu 那么 cpu 最高占用率可達 400%,top 里顯示的是把所有使用率加起來。

CPU 過高,這說明程序在進行計算密集型的操作,或者是線程死鎖,創建的線程過多等情況引起的。具體來說有哪些操作會導致 Java CPU 過高呢?

我總結了一下,一般有下面幾種情況發生

1.java 正則表達式使用不不當或者造成回溯導致CPU 100%
2.java線程死鎖,程序hang住
3.程序死循環,跳不出循環
4.不靠譜的算法

CPU過高排查

按照下面幾個步驟執行即可

步驟一:

使用 top 命令,查看占用 CPU 最高的進程。

Linux 系統,輸入 top 命令后,在輸入大寫 P,將以 CPU 占用率大小的順序排列進程列表。

步驟二:

在執行“top -Hp 進程PID”命令。進程PID 是上一步 top 命令找出來的。

例如:執行

top -Hp 28174 -d 1 -n 1

命令,查出占 CPU 最高的線程。

發現 20766 是最耗 CPU 的線程,轉換成 16 進制是 511e,再用 jstack 命令查看線程堆棧。

步驟三:

線程 ID 轉化,可以使用 printf “0x%x\n” 20766 命令。

步驟四:

然后再執行

jstack -l 20765 | grep 511e -A 20

命令,查看線程堆棧信息。

內存泄漏

內存泄露一般都是 HashMap,ArrayList,或者數據流沒被關閉,再者就是一些方法使用不當,漏洞等產生的內存泄露。比如 Jdk 1.6 中的 substring 等。

內存泄漏排查

泄漏排查過程如下

步驟一:

使用 jstat -gc pid 命令查看了 java 進程的 GC 狀態。如果在頻繁的發生 GC,那么你的程序肯定有問題。

例如下面的 Full Gc 一秒發生一次。

 步驟二:

需要保存了線程棧的現場和保存堆快照

//保存了線程棧的現場
jstack pid > jstack.log 

//保存堆快照
jmap -dump:format=b,file=heap.log pid 

再然后重啟服務,先讓程序恢復可用。

步驟三:

再接下來看看線程是否正常,可以執行以下命令:

grep 'java.lang.Thread.State' jstack.log  | wc -l
或者
grep -A 1 'java.lang.Thread.State' jstack.log  | grep -v 'java.lang.Thread.State' | sort | uniq -c |sort -n

看不出來也沒關系,使用 MAT 分析 jvm heap。知道你找到占用內存最大的對象,查看具體的代碼,解決問題,發布版本,更新程序。

 


免責聲明!

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



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