常見OOM問題之metaspace space元空間OOM問題詳解

本文來自于HeapDump性能社區(qū)! !有性能問題,上HeapDump性能社區(qū)!
正文:

Java 應(yīng)用程序只能使用有限的內(nèi)存量。您的特定應(yīng)用程序可以使用的確切內(nèi)存量是在應(yīng)用程序啟動期間指定的。為了讓事情變得更復(fù)雜,Java 內(nèi)存被分成不同的區(qū)域,如下圖所示:


1.png

所有這些區(qū)域的大小,包括元空間區(qū)域,都可以在 JVM 啟動期間指定。如果您不自己確定大小,將使用特定于平臺的默認(rèn)值。

所述java.lang.OutOfMemoryError:元空間中消息指示所述元空間區(qū)域在存儲器中被耗盡。

1,是什么原因造成的?

如果您不是 Java 領(lǐng)域的新手,您可能熟悉 Java 內(nèi)存管理中的另一個概念,稱為 PermGen。從 Java 8 開始,Java 中的內(nèi)存模型發(fā)生了重大變化。引入了一個名為 Metaspace 的新內(nèi)存區(qū)域,并刪除了 Permgen。做出此更改的原因有多種,包括但不限于:

  • permgen 所需的大小很難預(yù)測。它導(dǎo)致供應(yīng)不足觸發(fā)java.lang.OutOfMemoryError: Permgen size錯誤或過度供應(yīng)導(dǎo)致資源浪費。
  • GC 性能改進(jìn),啟用并發(fā)類數(shù)據(jù)取消分配,無需GC 暫停和元數(shù)據(jù)上的特定迭代器
  • 支持進(jìn)一步優(yōu)化,例如G1并發(fā)類卸載。

因此,如果您熟悉 PermGen,那么您需要了解的背景知識就是 – Java 8 之前 PermGen 中的任何內(nèi)容(類的名稱和字段、類的方法以及方法的字節(jié)碼、常量池、JIT 優(yōu)化等) ) – 現(xiàn)在位于元空間。

如您所見,元空間大小要求取決于加載的類的數(shù)量以及此類聲明的大小。所以很容易看到的主要原因java.lang.OutOfMemoryError:元空間是:太多的級別或過大的類加載到元空間。**

2,舉個例子

正如我們在前一章中解釋的那樣,元空間的使用與加載到 JVM 中的類的數(shù)量密切相關(guān)。下面的代碼是最直接的例子:

public class Metaspace {
    static javassist.ClassPool cp = javassist.ClassPool.getDefault();

    public static void main(String[] args) throws Exception{
        for (int i = 0; ; i++) { 
            Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass();
        }
    }
}

在這個例子中,源代碼遍歷一個循環(huán)并在運行時生成類。所有這些生成的類定義最終都會消耗 Metaspace。類生成的復(fù)雜性由javassist庫處理。

代碼將不斷生成新類并將它們的定義加載到 Metaspace,直到空間被完全利用并且java.lang.OutOfMemoryError: Metaspace被拋出。當(dāng)使用-XX:MaxMetaspaceSize=64m啟動時,在 Mac OS X 上,我的 Java 1.8.0_05 在加載了大約 70,000 個類時死亡。

3,解決辦法是什么?

面對由于 Metaspace 導(dǎo)致的 OutOfMemoryError 時,第一個解決方案應(yīng)該是顯而易見的。如果應(yīng)用程序耗盡了內(nèi)存中的 Metaspace 區(qū)域,您應(yīng)該增加 Metaspace 的大小。更改您的應(yīng)用程序啟動配置并增加以下內(nèi)容:

-XX:MaxMetaspaceSize=512m

上面的配置示例告訴 JVM,允許 Metaspace 增長到 512 MB,然后才能開始以OutOfMemoryError的形式抱怨。

乍一看,另一種解決方案甚至更簡單。您可以通過刪除此參數(shù)來完全取消對元空間大小的限制。但請注意,這樣做可能會引入大量交換和/或?qū)е卤緳C(jī)分配失敗。

不過,在結(jié)束之前,請注意 - 通常情況下,通過使用上述推薦的“快速修復(fù)”,您最終會通過隱藏java.lang.OutOfMemoryError: Metaspace而沒有解決潛在問題來掩蓋癥狀。如果您的應(yīng)用程序泄漏內(nèi)存或只是將一些不合理的內(nèi)容加載到 Metaspace 中,上述解決方案實際上不會改善任何事情,只會推遲問題。

Java OOM系列專題:

第一篇:Java OOM 原理篇 : 什么是 Java OOM

第二篇:Java OOM 基礎(chǔ)篇:常見的OutOfMemoryError 場景一:Java heap space 堆溢出問題詳解

第三篇:Java OOM 基礎(chǔ)篇:常見的OutOfMemoryError 場景二 : GC overhead limit exceeded 問題詳解

第四篇:Java OOM 基礎(chǔ)篇:常見的OutOfMemoryError 場景三: PermGen space 永久空間問題詳解

第五篇:Java OOM 基礎(chǔ)篇:常見的OutOfMemoryError 場景四: Permgen size 元空間問題詳解

第六篇:Java OOM 實戰(zhàn)篇:應(yīng)用故障之Java heap space 堆溢出實戰(zhàn)

第七篇:Java OOM 高級篇:體驗了一把線上CPU100%及應(yīng)用OOM的排查和解決過程

第八篇:Java OOM 高級篇:線上Docker 上Springboot程序OOM問題的排查分享

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容