虛擬機棧核心特性
- 線程私有:每條線程獨擁一個棧,生命週期與線程綁定。
- 描述方法執行內存模型:方法調用 ↔ 棧幀入棧/出棧。
棧幀四大組件
1. 局部變量表
- 存放:基本類型、對象引用、
returnAddress(字節碼指令地址)。
long/double 佔 2 個 Slot(32 位)。
- 編譯期確定大小,運行期不可動態擴展。
- 異常:
StackOverflowError:棧幀深度超限(遞歸過深)。
OutOfMemoryError:動態擴展失敗(無可用內存)。
2. 操作數棧
- 後進先出(LIFO),最大深度編譯期確定。
- 新建棧幀時為空,執行過程中:
- 從局部變量表複製常量/變量入棧。
- 執行運算、方法調用參數傳遞、返回值接收。
- 基本類型除
long/double 佔 2 深度外,其餘佔 1。
3. 動態連接
- 每個棧幀持有指向運行時常量池中該方法符號引用的指標。
- 支援方法調用過程中的動態解析:
符號引用(常量池)
→ 類加載/首次使用 → 直接引用(靜態解析:final/static/私有方法)
→ 每次運行期 → 直接引用(動態連接:虛方法、接口方法)
4. 方法返回地址
- 兩種退出方式:
- 正常返回:遇到返回字節碼指令(
ireturn、areturn 等)。
- 異常退出:拋出異常且未在方法內捕獲。
- 返回過程 = 當前棧幀出棧:
- 恢復上層局部變量表、操作數棧。
- 返回值壓入調用者操作數棧。
- PC 計數器指向調用指令下一條。
總結圖示
Thread Stack
┌─────────────────────┐
│ Frame N (current) │ ← 操作數棧、局部變量表、動態連接、返回地址
├─────────────────────┤
│ Frame N-1 (caller) │
├─────────────────────┤
│ ... │
├─────────────────────┤
│ Frame 1 (main) │
└─────────────────────┘