JVM參數最佳實踐:元空間的初始大小和最大大小


本文閱讀時間大約4分鍾。

640?wx_fmt=jpeg

JVM加載類的時候,需要記錄類的元數據,這些數據會保存在一個單獨的內存區域內,在Java 7里,這個空間被稱為永久代(Permgen),在Java 8里,使用元空間(Metaspace)代替了永久代。永久代和元空間保存的數據並不完全一樣,永久代中還保存另一些與類的元數據無關的雜項。

如我們之前的一篇文章

理論學習

使用Java 8以后,關於元空間的JVM參數有兩個:-XX:MetaspaceSize=N-XX:MaxMetaspaceSize=N,對於64位JVM來說,元空間的默認初始大小是20.75MB,默認的元空間的最大值是無限。MaxMetaspaceSize用於設置metaspace區域的最大值,這個值可以通過mxbean中的MemoryPoolBean獲取到,如果這個參數沒有設置,那么就是通過mxbean拿到的最大值是-1,表示無窮大。

由於調整元空間的大小需要Full GC,這是非常昂貴的操作,如果應用在啟動的時候發生大量Full GC,通常都是由於永久代或元空間發生了大小調整,基於這種情況,一般建議在JVM參數中將MetaspaceSize和MaxMetaspaceSize設置成一樣的值,並設置得比初始值要大,對於8G物理內存的機器來說,一般我會將這兩個值都設置為256M(PS:讀者可以根據自己的實際情況再調整)。

源碼分析

MetaspaceSize表示metaspace首次使用不夠而觸發FGC的閾值,只對觸發起作用,原因是:垃圾搜集器內部是根據變量 _capacity_until_GC來判斷metaspace區域是否達到閾值的,初始化代碼如下所示:

void MetaspaceGC::initialize() {	
  // Set the high-water mark to MaxMetapaceSize during VM initializaton since	
  // we can't do a GC during initialization.	
  _capacity_until_GC = MaxMetaspaceSize;	
}

GC收集器會在發生對metaspace的回收會,會計算新的capacityuntil_GC值,以后發生FGC就跟MetaspaceSize沒有關系了。640?wx_fmt=png

如果不設置MetaspaceSize,則默認的capacityuntil_GC為20M左右,具體代碼如下:640?wx_fmt=png

640

往期精選

640
640


640 本號專注於后端技術、JVM問題排查和優化、Java面試題、個人成長和自我管理等主題,為讀者提供一線開發者的工作和成長經驗,期待你能在這里有所收獲。

640?wx_fmt=png

文章好看就點這里
640


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM