內存總覽
堆區
Eden Space(伊甸園)
Survivor Space(倖存者區)
Tenured Gen(老年代-養老區)
非堆區
Code Cache(代碼緩存區)
Perm Gen(永久代)
Jvm Stack(java虛擬機棧)
Local Method Statck(本地方法棧)
Young Gen(年輕代)
1個Eden Space
1. 當對象在堆中創建後,會進入年輕代的Eden Space。
2. GC高頻掃描,每次掃描都會到失去引用的對象直接清理,然後將存活對象存入A Servivor Space。
A Survivor Space
3. GC中頻掃描,掃描到失去引用的對象直接清理,後將存活對象存入B Servivor Space
B Survivor Space(倖存者區),16此掃描放入老年代
4. GC中頻掃描,掃描到失去引用的對象直接清理,如果幾次掃描後對象仍然存在,則將其放入Old Gen。掃描完畢後jvm將Eden Space和兩個Survivor Space清空,並將兩個Survivor Space調換位置來減少內存碎片的產生。
Old Gen(老年代)
GC低頻掃描,每次掃描都會到失去引用的對象直接清理
字符串常量池
JDK1.7中JVM把String常量區從方法區中移除了;JDK1.8中JVM把String常量池移入了堆中,同時取消了“永久代”,改用元空間代替(Metaspace)
程序計數器
編譯時由所持引用計數,每個棧相互獨立,記錄的是正在執行的虛擬機字節碼指令地址,如果是本地方法則爲undefined
由於內存消耗很小几乎忽略不計,所以也是java中唯一不會拋出outofmemoryerroer的內存區域
非堆區/方法區
Perm Gen(永久代)1.8以後取消,改用元空間
永久代主要存放類定義、字節碼和常量等很少會變更的信息。
class文件信息
class文件常量池
運行時常量池
Code Cache
HotSpot Java虛擬機包括一個用於編譯和保存本地代碼(native code)的內存,叫做“代碼緩存區”(code cache)。
內存碎片處理
堆區
Young Gen
Young Gen垃圾回收時,採用將存活對象複製到到空的Suvivor Space的方式來確保儘量不存在內存碎片,採用空間換時間的方式來加速內存中不再被持有的對象儘快能夠得到回收。
Tenured Gen
採用壓縮的方式來避免內存碎片(將存活對象移動到內存片的一邊,也就是內存整理)。當然,有些垃圾回收器(譬如CMS垃圾回收器)出於效率的原因,可能會不進行壓縮。