永久代和元空間的變化
隨著JDK8的到來,JVM不再有PermGen。但類的後設資料資訊(metadata)還在,只不過不再是儲存在連續的堆空間上,而是移動到叫做“Metaspace”的本地記憶體(Native memory)中。
其實,移除永久代的工作從JDK1.7就開始了。JDK1.7中,儲存在永久代的部分資料就已經轉移到了Java Heap或者是 Native Heap。但永久代仍存在於JDK1.7中,並沒完全移除,譬如符號引用(Symbols)轉移到了native heap;字面量(interned strings)轉移到了java heap(上一篇文章Java-String.intern的深入研究 有專門提到這個變化);類的靜態變數(class statics)轉移到了java heap。
類的後設資料資訊轉移到Metaspace的原因是PermGen很難調整。PermGen中類的後設資料資訊在每次FullGC的時候可能會被收集,但成績很難令人滿意。而且應該為PermGen分配多大的空間很難確定,因為PermSize的大小依賴於很多因素,比如JVM載入的class的總數,常量池的大小,方法的大小等。
此外,在HotSpot中的每個垃圾收集器需要專門的程式碼來處理儲存在PermGen中的類的後設資料資訊。從PermGen分離類的後設資料資訊到Metaspace,由於Metaspace的分配具有和Java Heap相同的地址空間,因此Metaspace和Java Heap可以無縫的管理,而且簡化了FullGC的過程,以至將來可以並行的對後設資料資訊進行垃圾收集,而沒有GC暫停。
深入理解元空間(Metaspace)
元空間的記憶體大小
元空間是方法區的在HotSpot jvm 中的實現,方法區主要用於儲存類的資訊、常量池、方法資料、方法程式碼等。方法區邏輯上屬於堆的一部分,但是為了與堆進行區分,通常又叫“非堆”。
元空間的本質和永久代類似,都是對JVM規範中方法區的實現。不過元空間與永久代之間最大的區別在於:元空間並不在虛擬機器中,而是使用本地記憶體。,理論上取決於32位/64位系統可虛擬的記憶體大小。可見也不是無限制的,需要配置引數。
為什麼廢棄永久代 ?
絕大部分 Java 程式設計師應該都見過 "java.lang.OutOfMemoryError: PermGen space "這個異常。這裡的 “PermGen space”其實指的就是方法區。不過方法區和“PermGen space”又有著本質的區別。前者是 JVM 的規範,而後者則是 JVM 規範的一種實現,並且只有 HotSpot 才有 “PermGen space”,而對於其他型別的虛擬機器,如 JRockit(Oracle)、J9(IBM) 並沒有“PermGen space”。由於方法區主要儲存類的相關資訊,所以對於動態生成類的情況比較容易出現永久代的記憶體溢位。最典型的場景就是,在 jsp 頁面比較多的情況,容易出現永久代記憶體溢位。
1. 官方解釋
參照JEP122:http://openjdk.java.net/jeps/122,原文擷取:
Motivation
This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.
即:移除永久代是為融合HotSpot JVM與 JRockit VM而做出的努力,因為JRockit沒有永久代,不需要配置永久代。
2.現實中易出問題
a、字串存在永久代中,容易出現效能問題和記憶體溢位。
b、類及方法的資訊等比較難確定其大小,因此對於永久代的大小指定比較困難,太小容易出現永久代溢位,太大則容易導致老年代溢位。
c、永久代會為 GC 帶來不必要的複雜度,並且回收效率偏低。
元空間的調優
元空間的本質和永久代類似,都是對JVM規範中方法區的實現。不過元空間與永久代之間最大的區別在於:元空間並不在虛擬機器中,而是使用本地記憶體。因此,預設情況下,元空間的大小僅受本地記憶體限制,但可以通過以下引數來指定元空間的大小:
-XX:MaxMetaspaceSize引數可以設定元空間的最大值,預設是沒有上限的,也就是說你的系統記憶體上限是多少它就是多少。
-XX:MetaspaceSize選項指定的是元空間的初始大小,如果沒有指定的話,元空間會根據應用程式執行時的需要動態地調整大小,達到該值就會觸發垃圾收集進行型別解除安裝,同時GC會對該值進行調整:如果釋放了大量的空間,就適當降低該值;如果釋放了很少的空間,那麼在不超過MaxMetaspaceSize時,適當提高該值。
MaxMetaspaceSize的調優
- -XX:MaxMetaspaceSize={unlimited}
- 元空間的大小受限於你機器的記憶體
- 限制類的後設資料使用的記憶體大小,以免出現虛擬記憶體切換以及本地記憶體分配失敗。如果懷疑有類載入器出現洩露,應當使用這個引數;32位機器上,如果地址空間可能會被耗盡,也應當設定這個引數。
- 元空間的初始大小是21M——這是GC的初始的高水位線,超過這個大小會進行Full GC來進行類的回收。
- 如果啟動後GC過於頻繁,請將該值設定得大一些
- 可以設定成和持久代一樣的大小,以便推遲GC的執行時間
除了上面兩個指定大小的選項以外,還有兩個與 GC 相關的屬性:
-XX:MinMetaspaceFreeRatio,在GC之後,最小的Metaspace剩餘空間容量的百分比,減少為分配空間所導致的垃圾收集 -XX:MaxMetaspaceFreeRatio,在GC之後,最大的Metaspace剩餘空間容量的百分比,減少為釋放空間所導致的垃圾收集
參考文章:https://www.cnblogs.com/yulei126/p/6777323.html
https://blog.csdn.net/zhushuai1221/article/details/52122880
相關文章
- 為什麼用元空間替代永久代?
- 【深入理解JVM】方法區 永久代 元空間JVM
- JDK8-廢棄永久代(PermGen)迎來元空間(Metaspace)JDK
- 2.5.6 建立預設的永久表空間
- Java面試題虛擬機器為什麼使用元空間替換了永久代(JVM篇)Java面試題虛擬機JVM
- 環境變數和地址空間變數
- [20211011]跟蹤freespace空間的變化情況.txt
- 張亞勤|物理世界和元空間(RSR)
- 潘雲鶴院士:人工智慧走向2.0的本質原因——人類世界正由兩元空間變成三元空間人工智慧
- Jordan標準形2——如何把空間V分解成A的不變子空間的直和
- MySQL空間最佳化(空間清理)MySql
- JVM永久代JVM
- 時間和空間的完美統一!阿里雲時空資料庫正式商業化阿里資料庫
- 元宇宙是資料空間?大資料時代的新趨勢來了元宇宙大資料
- 坑系列 — 時間和空間的平衡
- 眾創空間,符合時代需求
- 揭秘空間站模型3D視覺化新紀元模型3D視覺化
- JVM元空間Metaspace的記憶體結構JVM記憶體
- 空間剪枝最佳化
- MySQL共享表空間各個版本之間的演變圖MySql
- 硬碟空間的管理和分割槽硬碟
- 特徵向量、神經元以及特徵空間特徵
- 眾創空間,實現創業者現代化辦公模式更新創業模式
- (七)永久代(方法區)的垃圾回收
- JVM - 方法區(永久代)的垃圾回收JVM
- games101-1 光柵化與光線追蹤中的空間變換GAM
- PCIE配置和地址空間
- 使用p名稱空間和c名稱空間的XML快捷方式XML
- shell(2)永久環境變數和字串顯位變數字串
- python設定環境變數(臨時和永久)Python變數
- 真實系統(Real systems)通常表現出空間變化(spatial variation)
- 線性代數應該這樣學6:積空間,商空間,多項式
- Java9後String的空間優化Java優化
- 從零到一, 打造全新的遊戲次元空間遊戲
- 刪除檔案後儲存空間容量沒有變化怎麼辦?
- C和C++中的名字空間和作用域C++
- C盤空間莫名其妙變小怎麼辦 C盤空間不足的解決辦法
- 表空間和資料檔案的管理