JVM 核心定位
JVM (Java Virtual Machine) 是 Java 程序運行的虛擬機器,負責將字節碼轉換為機器指令、管理運行時內存、調度線程與硬件資源。JDK 包含 JRE,JRE 包含基礎類庫與 JVM。
Java 程序執行流程
- 源碼
.java → 編譯器 → 字節碼 .class
- 類加載器讀取字節碼 → 方法區
- 執行引擎解釋/編譯執行 → 操作棧、堆、本地方法棧
- 通過 JNI 調用本地庫 → 操作系統 → 硬件
運行時數據區六大區域

1. 程序計數器 (Program Counter Register)
線程私有,記錄當前線程執行的字節碼地址。唯一不會發生 OutOfMemoryError 的區域。
2. Java 虛擬機棧 (JVM Stack)
線程私有,生命周期與線程同步。每個方法調用對應一個棧幀,存儲:
- 局部變量表(基本類型、對象引用、returnAddress)
- 操作數棧
- 動態鏈接(指向運行時常量池的方法引用)
- 方法出口(正常返回/異常拋出)
3. 本地方法棧 (Native Method Stack)
與虛擬機棧類似,服務於 native 方法(C/C++ 實現)。HotSpot 將兩者合併實現。
4. 方法區 (Method Area)
線程共享,存儲:
- 類信息(版本、字段、方法、接口)
- 運行時常量池(字面量、符號引用)
- 靜態變量
- 即時編譯器生成的機器碼
JDK 8 移除永久代,改用元空間(Metaspace,本地內存)。
5. Java 堆 (Java Heap)
線程共享,最大區域,存放對象實例與數組。GC 主要作用區,分代收集:新生代(Eden、Survivor)、老年代。可通過 -Xms/-Xmx 控制大小。
6. 運行時常量池 (Runtime Constant Pool)
方法區一部分,存放編譯期生成的字面量、符號引用,具備動態性(String.intern() 可運行期添加)。
內存溢出典型場景
- StackOverflowError:遞歸過深、棧幀過大(
-Xss 調大)
- OutOfMemoryError: Heap:對象持有引用無法回收、堆過小(
-Xmx 調大)
- OutOfMemoryError: Metaspace:動態生成大量類(JSP、動態代理、CGLIB)
- OutOfMemoryError: Direct Buffer:NIO 直接內存未釋放(
-XX:MaxDirectMemorySize)