本文主要講述一下jvm的PermGen與Metaspacehtml
對於垃圾收集算法來講,分代回收是高級算法之一。對象按照生成時間進行分代,剛剛生成不久的年輕對象劃爲新生代(Young gen-eration),而存活了較長時間的對象劃爲老生代(Old generation)。根據具體實現方式的不一樣,可能還會劃分更多的代。好比有的把永久代也算作一個代。java
java memory主要分heap memory 和 non-heap memory,其計算公式以下:算法
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]
按分代,分young-eden,young-survivor,old
用-Xmn,-Xms,-Xmx來指定
包括metaspace,thread stacks,compiled native code,memory allocated by native codesegmentfault
-XX:PermSize或-XX:MetaspceSize,-Xss或-XX:ThreadStackSize
全部的被intern的String被存儲在PermGen區.PermGen區使用-XX:MaxPermSize=N來設置最大大小,可是因爲應用程序string.intern一般是不可預測和不可控的,所以很差設置這個大小。設置很差的話,經常會引發
java.lang.OutOfMemoryError: PermGen space
字符串常量池被限制在整個應用的堆內存中,在運行時調用String.intern()增長字符串常量不會使永久代OOM了。併發
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與PermGen之間最大的區別在於:Metaspace並不在虛擬機中,而是使用本地內存。
若是沒有使用-XX:MaxMetaspaceSize來設置類的元數據的大小,其最大可利用空間是整個系統內存的可用空間。JVM也能夠增長本地內存空間來知足類元數據信息的存儲。
可是若是沒有設置最大值,則可能存在bug致使Metaspace的空間在不停的擴展,會致使機器的內存不足;進而可能出現swap內存被耗盡;最終致使進程直接被系統直接kill掉。
若是類元數據的空間佔用達到MaxMetaspaceSize設置的值,將會觸發對象和類加載器的垃圾回收。jvm
java.lang.OutOfMemoryError: Metaspace space
JVM從Metaspace在捕獲一個一個內存分配失敗後拋出。
將常量池從PermGen剝離到heap中,將元數據從PermGen剝離到元數據區,去除PermGen的好處以下:優化
在PermGen中元數據可能會隨着每一次Full GC發生而進行移動。HotSpot虛擬機的每種類型的垃圾回收器都須要特殊處理PermGen中的元數據,分離出來之後能夠簡化Full GC以及對之後的併發隔離類元數據等方面進行優化。
PermGen是HotSpot的實現特有的,JRockit並無PermGen一說