令人頭痛的java.lang.OutOfMemoryError:GC overhead limit exceeded

jmap+jvisualvm 分析系統中的 java.lang.OutOfMemoryError:GC overhead limit exceeded

2019-11-21 星期六、一大早一個釘釘的語音通知工單系統掛了。
馬上洗漱完跑到公司,打開遠程服務器看了一下報錯信息!

java.lang.OutOfMemoryError:GC overhead limit exceeded

???內存溢出
首先重啓一下服務器(心想這個可能是偶發性吧估計誰在做什麼比較消耗資源的東西,想着重啓這一下就能解決)

五分鐘過後又報出了GC overhead limit exceeded,看了一下服務器內存確實不夠,但是平時

接着百度一下GC overhead limit exceeded,有文章解釋道:

這個是JDK6新添的錯誤類型。是發生在GC佔用大量時間爲釋放很小空間的時候發生的,是一種保護機制。一般是因爲堆太小,導致異常的原因:沒有足夠的內存。
Sun 官方對此的定義:超過98%的時間用來做GC並且回收了不到2%的堆內存時會拋出此異常。

解決方案

  1. 查看代碼中是否有死循環;
  2. 增大堆內存
    JAVA_OPTS=-server -Xms512m -Xmx1024m -XX:MaxNewSize=1024m -XX:MaxPermSize=1024m ;
  3. 清除linux 緩存
    echo 3 > /proc/sys/vm/drop_caches

上面的方案全試了一遍之後,問題依舊沒解決
最後使用 jmap 生成dump 文件,用jvisualvm 分析之後成功定位問題。

一. jmap 成功dump文件

##pid 爲項目進程id   /mnt/oom.phrof 爲文件路徑
jmap -dump:format=b,file=/mnt/oom.phrof  pid

如果上方提示jmap命令不存在使用java命令which java獲取jdk的安裝路徑

which java
## 進入上面輸出的jdk安裝路徑
cd /usr/local/java/jdk/jdk1.8/bin/
./jmap -dump:format=b,file=/mnt/oom.phrof pid

二. 下載dump文件到本地

## 首先壓縮一下dump文件(文件太大壓縮過後下載更快)
zip oom2.zip /mnt/oom.phrof
## 下載
sz /mnt/oom.phrof

三.使用jvisualvm 打開dump文件

解壓下載下來的oom2.zip 得到oom.phrof 文件
雙擊打開本地jdk的bin目錄下的jvisualvm.exe,點擊菜單-文件->裝入oom.phrof

在這裏插入圖片描述

對比發現線上的HashMap的示例數異常,找了最近提交的代碼 發現了這個bug
在這裏插入圖片描述

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