概述
基於《深入理解 Java 虛擬機》(Java SE 7 版)整理。JVM 在執行程序時,將內存劃分為多個功能各異、生命周期不同的區域,統稱為運行時數據區。

核心區域詳解
1. 程序計數器
- 極小的內存空間,可視為當前線程執行的字節碼行號指示器。
- 字節碼解釋器通過改變此值選取下一條指令。
- 線程私有,隨線程創建而生、隨線程結束而亡。
- 執行 Java 方法時記錄字節碼地址;執行 Native 方法時值為 undefined。
- 唯一不會拋出 OutOfMemoryError 的區域。
2. Java 虛擬機棧
- 線程私有,描述 Java 方法執行的內存模型。
- 每個方法調用對應一個棧幀,包含:局部變量表、操作數棧、動態鏈接、方法出口。
- 局部變量表存放編譯期可知的基本類型、引用類型、returnAddress 類型;大小在編譯期確定,運行期不變。
- 兩類異常:
StackOverflowError(棧深度不足)、OutOfMemoryError(動態擴展失敗)。
3. 本地方法棧
- 與虛擬機棧類似,但服務於 Native 方法。
- JVM 規範未強制其語言、數據結構,由具體實現決定(HotSpot 合併兩棧)。
- 同樣拋出
StackOverflowError 和 OutOfMemoryError。
4. Java 堆
- 所有線程共享,JVM 啟動時創建,主要存放對象實例與數組。
- 垃圾收集器管理的主戰場,又稱 GC 堆。
- 邏輯上可劃分為新生代、老年代(回收視角);或劃分為線程私有分配緩衝區(分配視角)。
- 物理上可不連續,邏輯連續即可;支持固定或可擴展大小。
- 無法分配實例時拋出
OutOfMemoryError。
5. 方法區
- 線程共享,存儲類信息、常量、靜態變量、即時編譯器編譯後的代碼。
- 邏輯連續、物理可不連續;支持固定/可擴展。
- 垃圾回收針對常量池回收、類型卸載;早期版本曾因類型卸載不當導致嚴重內存洩漏。
6. 運行時常量池
- 屬於方法區一部分。Class 文件中的字面量、符號引用在類加載後進入此池。
- 運行期可通過
String.intern() 動態添加字符串常量。
- 無法申請內存時拋出
OutOfMemoryError。