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。知道你找到占用內存最大的對象,查看具體的代碼,解決問題,發布版本,更新程序。