對JVM規範中方法區的實現。java
絕大部分 Java 程序員應該都見過 "java.lang.OutOfMemoryError: PermGen space "這個異常。這裏的 「PermGen space」其實指的就是方法區。不過方法區和「PermGen space」又有着本質的區別。前者是 JVM 的規範,然後者則是 JVM 規範的一種實現,而且只有 HotSpot 纔有 「PermGen space」,而對於其餘類型的虛擬機,如 JRockit(Oracle)、J9(IBM) 並無「PermGen space」。因爲方法區主要存儲類的相關信息,因此對於動態生成類的狀況比較容易出現永久代的內存溢出。最典型的場景就是,在 jsp 頁面比較多的狀況,容易出現永久代內存溢出。程序員
其實,移除永久代的工做從JDK1.7就開始了。JDK1.7中,存儲在永久代的部分數據就已經轉移到了Java Heap或者是 Native Heap。但永久代仍存在於JDK1.7中,並沒徹底移除,譬如符號引用(Symbols)轉移到了native heap;字面量(interned strings)轉移到了java heap;類的靜態變量(class statics)轉移到了java heap。jsp
元空間的本質和永久代相似,都是對JVM規範中方法區的實現。不過元空間與永久代之間最大的區別在於:元空間並不在虛擬機中,而是使用本地內存。所以,默認狀況下,元空間的大小僅受本地內存限制,但能夠經過如下參數來指定元空間的大小:spa
-XX:MetaspaceSize,初始空間大小,達到該值就會觸發垃圾收集進行類型卸載,同時GC會對該值進行調整:若是釋放了大量的空間,就適當下降該值;若是釋放了不多的空間,那麼在不超過MaxMetaspaceSize時,適當提升該值。
-XX:MaxMetaspaceSize,最大空間,默認是沒有限制的。內存
除了上面兩個指定大小的選項之外,還有兩個與 GC 相關的屬性:
-XX:MinMetaspaceFreeRatio,在GC以後,最小的Metaspace剩餘空間容量的百分比,減小爲分配空間所致使的垃圾收集
-XX:MaxMetaspaceFreeRatio,在GC以後,最大的Metaspace剩餘空間容量的百分比,減小爲釋放空間所致使的垃圾收集虛擬機
最後咱們來看一下Metaspace相關的幾個JVM參數:string
| 參數名it
|io
做 用class
| |
MetaspaceSize
|
初始化的Metaspace大小,控制Metaspace發生GC的閾值。GC後,動態增長或者下降MetaspaceSize,默認狀況下,這個值大小根據不一樣的平臺在12M到20M之間浮動
| |
MaxMetaspaceSize
|
限制Metaspace增加上限,防止由於某些狀況致使Metaspace無限使用本地內存,影響到其餘程序,默認爲4096M
| |
MinMetaspaceFreeRatio
|
當進行過Metaspace GC以後,會計算當前Metaspace的空閒空間比,若是空閒比小於這個參數,那麼虛擬機增加Metaspace的大小,默認爲40,即70%
| |
MaxMetaspaceFreeRatio
|
當進行過Metaspace GC以後,會計算當前Metaspace的空閒空間比,若是空閒比大於這個參數,那麼虛擬機會釋放部分Metaspace空間,默認爲70,即70%
| |
MaxMetaspaceExpanison
|
Metaspace增加時的最大幅度,默認值爲5M
| |
MinMetaspaceExpanison
|
Metaspace增加時的最小幅度,默認爲330KB
|