聊聊jvm的PermGen與Metaspace

轉載:https://segmentfault.com/a/1190000012577387

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

java memory結構

分代概念

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

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 codesegmentfault

-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設置的值,將會觸發對象和類加載器的垃圾回收。jvm

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

相關文章
相關標籤/搜索