首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JVM 內存模型權威解析:五大運行時數據區結構與線程共享/私有邊界

     編輯:Java 綜合教學

一、五大運行時數據區總覽

基於《深入理解 Java 虛擬機》JDK 1.6 規範(JDK 1.8+ 部分區域有變化,文中標註)。

JVM 內存模型圖
區域線程共享性核心職責JDK 1.8+ 變化
堆✅ 共享對象實例分配區,GC 主戰場無本質變化,默認開啟壓縮指針
方法區✅ 共享類元數據、常量、靜態變量、JIT 代碼元空間 替換永久代,移至本地內存
虛擬機棧❌ 私有Java 方法執行:棧幀(局部變量表、操作數棧、動態鏈接、返回地址)-Xss 調整棧大小
本地方法棧❌ 私有Native 方法執行服務同上
程序計數器❌ 私有當前線程執行字節碼行號指示器唯一無 OOM 區域

二、核心區域深度解析

1. 程序計數器

  • 極小內存空間,字節碼解析器工作指針
  • 線程私有,上下文切換時保存/恢復執行位置
  • 唯一規範中規定不會 OutOfMemoryError 的區域

2. Java 虛擬機棧

  • 描述 Java 方法執行內存模型
  • 棧幀:方法調用 → 入棧;方法返回 → 出棧
  • 棧幀結構:
    • 局部變量表:基本類型、對象引用、returnAddress
    • 操作數棧:運算中間結果、參數傳遞
    • 動態鏈接:指向運行時常量池方法引用
    • 方法出口:正常返回/異常拋出地址
  • 異常:StackOverflowError(深度過大)、OutOfMemoryError(擴展失敗)

3. 本地方法棧

  • 服務 native 方法(C/C++ 實現)
  • HotSpot 合併虛擬機棧與本地方法棧
  • 同樣拋出 StackOverflowError/OutOfMemoryError

4. Java 堆

  • JVM 管理最大塊內存,啟動參數 -Xms/-Xmx 控制
  • 對象實例幾乎全部在此分配(逃逸分析優化除外)
  • GC 分代收集:新生代 + 老年代
  • 線程共享,但可劃分線程本地分配緩衝 (TLAB) 提升分配效率

5. 方法區

  • 存儲:已加載類信息、常量、靜態變量、即時編譯器代碼緩存
  • JDK 1.6:永久代,參數 -XX:PermSize/-XX:MaxPermSize
  • JDK 1.7:符號引用/字符串常量池移至堆
  • JDK 1.8+:永久代移除 → 元空間,使用本地內存,參數 -XX:MetaspaceSize/-XX:MaxMetaspaceSize
  • 運行時常量池屬於方法區一部分,String.intern() 可動態擴充

三、線程共享 vs 私有 記憶口訣

「一堆一區共天下,兩棧一計自家珍」

  • 共享:堆、方法區
  • 私有:虛擬機棧、本地方法棧、程序計數器

四、常見面試題陷阱

題目陷阱點正確答案
對象一定在堆上分配嗎?忽略逃逸分析不一定。標量替換、棧上分配、鎖消除可使對象不進堆
方法區就是永久代嗎?混淆規範與實現方法區是規範,永久代是 HotSpot 1.7 前實現,1.8 用元空間實現
局部變量線程安全嗎?忽略引用逃逸基本類型安全;引用類型若未逃逸出方法則安全
常量池在哪?版本不清1.6 PermGen;1.7 堆;1.8+ 堆(字符串常量池),類常量池在元空間

五、參考資料

周志明. 深入理解 Java 虛擬機:JVM 高級特性與最佳實踐 (第 2/3 版). 機械工業出版社.

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved