一次java.lang.OutOfMemoryError: Metaspace處理

其實這個問題非常明顯就是Metaspace內存不夠導致溢出,調整jvm的-XX:MetaspaceSize=56m -XX:MaxMetaspaceSize=128m元空間大小參數就能解決。但是根據甲方要求,必須要給出明確的解釋,排除是否是內存泄露導致的OutOfMemoryError: Metaspac報錯。沒有辦法,甲方爸爸的要求。那就找點證據說明就是內存給小了的問題。

由於之前的容器已經清除,只能在配置一樣的環境中分析。 首先查看當前jvm Metaspace分配的空間大小。我是通過arthas的jvm命令進行查看的。 首先拉去arthas的jar包。

curl -O https://arthas.aliyun.com/arthas-boot.jar

然後將jar複製到你要查看項目的docker容器中去

docker cp ./arthas-boot.jar  {容器名稱或id}:/home/

進入容器

docker exec -it {容器名稱或id} sh

啓動arthas-boot.jar

java -jar arthas-boot.jar

看到以上證明啓動成功

輸入jvm查看jvm信息

和啓動配置是一致的。(退出arthas最好使用stop,不然在其他docker中啓動會監控的依然是這個項目。) arthas文檔地址:https://arthas.aliyun.com/doc/install-detail.html 這個工具功能還有很多比如監控代碼執行時間等等。

接下來使用jstat查看項目的gc狀況 在容器中輸入jps,然後就可以使用jstat命令查看。輸入jstat -gcutil pid查看gc概要信息

列名稱 描述
S0 S0(Survivor 0)空間使用百分比(相對於當前容量)
S1 S1(Survivor 1)空間使用百分比(相對於當前容量)
E Eden空間使用百分比(相對於當前容量)
O 老年代空間使用百分比(相對於當前容量)
M 元空間(Metaspace)使用百分比(相對於當前容量)
CCS CCS空間使用百分比
YGC 新生代GC(Minor GC/Young GC)發生的次數
YGCT YGC所消耗的時間, 單位s
FGC Full GC發生的次數
FGCT Full GC消耗的時間, 單位s
GCT 所有GC消耗的總時間, 單位s

通過上圖分析新生代發生了大量的gc,導致老年代數據快速積壓,然後發生Full GC。 接下來將jvm的加載類使用jmap dump下來到本地分析查看。

jmap -dump:live,format=b,file=dump.hprof 6

可以看到本地生成了個dump.hprof 文件

將它拉取到本地,使用JProfiler打開 JProfiler官網:https://www.ej-technologies.com/products/jprofiler/overview.html

這些類點進去看看是否有大量創建的異常類

發現沒有異常創建的類,分析就是單純的空間給小了。加大元空間容量分配-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m 再運行2天看看gc狀況

發現新生代gc2w多次,Full GC次數爲0,gc大部分都發生在新生代。說明配置有效。 這是我第一次實戰調優,要是哪裏有問題請指出,互相學習一下。

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