聊聊jvm的PermGen與Metaspace

weixin_34370347發表於2017-12-26

本文主要講述一下jvm的PermGen與Metaspace

java memory結構

分代概念

對於垃圾收集演算法來說,分代回收是高階演算法之一。物件按照生成時間進行分代,剛剛生成不久的年輕物件劃為新生代(Young gen-eration),而存活了較長時間的物件劃為老生代(Old generation)。根據具體實現方式的不同,可能還會劃分更多的代。比如有的把永久代也算做一個代。

memory劃分

java memory主要分heap memory 和 non-heap memory,其計算公式如下:

Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]
複製程式碼

  • heap結構

按分代,分young-eden,young-survivor,old 用-Xmn,-Xms,-Xmx來指定

  • non-heap結構

包括metaspace,thread stacks,compiled native code,memory allocated by native code

-XX:PermSize或-XX:MetaspceSize,-Xss或-XX:ThreadStackSize

PermGen與Metaspace

字串常量池的變化

  • 在java7的時候將字串常量池則移到java heap

所有的被intern的String被儲存在PermGen區.PermGen區使用-XX:MaxPermSize=N來設定最大大小,但是由於應用程式string.intern通常是不可預測和不可控的,因此不好設定這個大小。設定不好的話,常常會引起

java.lang.OutOfMemoryError: PermGen space
複製程式碼
  • java7,8的字串常量池在堆中實現 字串常量池被限制在整個應用的堆記憶體中,在執行時呼叫String.intern()增加字串常量不會使永久代OOM了。

方法區的變化

  • java8的時候去除PermGen,將其中的方法區移到non-heap中的Metaspace

move name and fields of the class, methods of a class with the bytecode of the methods, constant pool, JIT optimizations etc to metaspace

  • Metaspace屬於non-heap

Metaspace與PermGen之間最大的區別在於:Metaspace並不在虛擬機器中,而是使用本地記憶體。

如果沒有使用-XX:MaxMetaspaceSize來設定類的後設資料的大小,其最大可利用空間是整個系統記憶體的可用空間。JVM也可以增加本地記憶體空間來滿足類後設資料資訊的儲存。 但是如果沒有設定最大值,則可能存在bug導致Metaspace的空間在不停的擴充套件,會導致機器的記憶體不足;進而可能出現swap記憶體被耗盡;最終導致程式直接被系統直接kill掉。

  • OOM異常 如果類後設資料的空間佔用達到MaxMetaspaceSize設定的值,將會觸發物件和類載入器的垃圾回收。
java.lang.OutOfMemoryError: Metaspace space
複製程式碼

JVM從Metaspace在捕獲一個一個記憶體分配失敗後丟擲。

Metaspace相關引數

  • -XX:MetaspaceSize,初始空間大小,達到該值就會觸發垃圾收集進行型別解除安裝,同時GC會對該值進行調整:如果釋放了大量的空間,就適當降低該值;如果釋放了很少的空間,那麼在不超過MaxMetaspaceSize時,適當提高該值。
  • -XX:MaxMetaspaceSize,最大空間,預設是沒有限制的。
  • -XX:MinMetaspaceFreeRatio,在GC之後,最小的Metaspace剩餘空間容量的百分比,減少為分配空間所導致的垃圾收集
  • -XX:MaxMetaspaceFreeRatio,在GC之後,最大的Metaspace剩餘空間容量的百分比,減少為釋放空間所導致的垃圾收集

小結

將常量池從PermGen剝離到heap中,將後設資料從PermGen剝離到後設資料區,去除PermGen的好處如下:

  • 將字串常量池從PermGen分離出來,與類後設資料分開,提升類後設資料的獨立性
  • 將後設資料從PermGen剝離出來到Metaspace,可以提升對後設資料的管理同時提升GC效率。

在PermGen中後設資料可能會隨著每一次Full GC發生而進行移動。HotSpot虛擬機器的每種型別的垃圾回收器都需要特殊處理PermGen中的後設資料,分離出來以後可以簡化Full GC以及對以後的併發隔離類後設資料等方面進行優化。

  • 為後續將HotSpot與JRockit合二為一做準備。

PermGen是HotSpot的實現特有的,JRockit並沒有PermGen一說

doc

相關文章