Full GC (Metadata GC Threshold)

weixin_33895657發表於2018-11-28

Metaspace參考:https://blog.csdn.net/xlnjulp/article/details/46763045

#首先排查JVM的問題,就要把GC日誌開啟

-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC

Full GC (Metadata GC Threshold)原因描述

通過GC日誌可以看到,old區離最大配置還很遠,Metaspace區並沒有真正釋放空間,所以懷疑是Metaspace區不夠用了。

以前只認為,Metaspace區是儲存在本地記憶體中,是沒有上限的,經查閱資料才發現,原來JDK8中,XX:MaxMetaspaceSize確實是沒有上限的,最大容量與機器的記憶體有關;但是XX:MetaspaceSize是有一個預設值的:21M。問題就出在這裡。

#Full GC (Metadata GC Threshold)最終解決方案

既然問題找到了,那麼就設定一個XX:MetaspaceSize的JVM啟動引數:-XX:MetaspaceSize=128M.


#Metaspace配置說明

從JDK8開始,永久代(PermGen)的概念被廢棄掉了,取而代之的是一個稱為Metaspace的儲存空間。Metaspace使用的是本地記憶體,而不是堆記憶體,也就是說在預設情況下Metaspace的大小隻與本地記憶體大小有關。當然你也可以通過以下的幾個引數對Metaspace進行控制:

* -XX:MetaspaceSize=N *

這個引數是初始化的Metaspace大小,該值越大觸發Metaspace GC的時機就越晚。隨著GC的到來,虛擬機器會根據實際情況調控Metaspace的大小,可能增加上線也可能降低。在預設情況下,這個值大小根據不同的平臺在12M到20M浮動。使用java -XX:+PrintFlagsInitial命令檢視本機的初始化引數,-XX:Metaspacesize為21810376B(大約20.8M)。

-XX:MaxMetaspaceSize=N

這個引數用於限制Metaspace增長的上限,防止因為某些情況導致Metaspace無限的使用本地記憶體,影響到其他程式。在本機上該引數的預設值為4294967295B(大約4096MB)。

-XX:MinMetaspaceFreeRatio=N

當進行過Metaspace GC之後,會計算當前Metaspace的空閒空間比,如果空閒比小於這個引數,那麼虛擬機器將增長Metaspace的大小。在本機該引數的預設值為40,也就是40%。設定該引數可以控制Metaspace的增長的速度,太小的值會導致Metaspace增長的緩慢,Metaspace的使用逐漸趨於飽和,可能會影響之後類的載入。而太大的值會導致Metaspace增長的過快,浪費記憶體。

-XX:MaxMetasaceFreeRatio=N

當進行過Metaspace GC之後, 會計算當前Metaspace的空閒空間比,如果空閒比大於這個引數,那麼虛擬機器會釋放Metaspace的部分空間。在本機該引數的預設值為70,也就是70%。

-XX:MaxMetaspaceExpansion=N

Metaspace增長時的最大幅度。在本機上該引數的預設值為5452592B(大約為5MB)。

-XX:MinMetaspaceExpansion=N

Metaspace增長時的最小幅度。在本機上該引數的預設值為340784B(大約330KB為)。


#

相關文章