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

JVM 運行時數據區詳解:程序計數器、棧、堆、方法區、直接內存全景圖

     編輯:Java 綜合教學

JVM 內存模型權威指南:七大運行時數據區結構與異常場景

《Java 虛擬機規範》定義了 JVM 運行時數據區,理解各區域職能、線程共享性、異常觸發條件,是排查 OOM、棧溢出、元空間耗盡等生產故障的理論基石。

JVM 運行時數據區示意圖

1. 程序計數器 - 線程私有

  • 角色:當前線程執行的字節碼行號指示器。
  • 功能:分支、循環、跳轉、異常處理、線程恢復均依賴計數器。
  • 特點:唯一不會拋出 OutOfMemoryError的區域;每線程獨立,互不干擾。

2. Java 虛擬機棧 - 線程私有

  • 生命周期:與線程同步。
  • 棧幀結構:局部變量表、操作數棧、動態鏈接、方法出口。
  • 局部變量表:基本類型、對象引用、returnAddress;編譯期確定大小,運行期不變。
  • 兩大異常:
    • StackOverflowError:棧深度超過虛擬機限制(遞歸過深)。
    • OutOfMemoryError:動態擴展時無法申請足夠內存。

3. 本地方法棧 - 線程私有

  • 服務 native 方法,規範未強制實現細節(HotSpot 合併至 Java 棧)。
  • 同樣拋出 StackOverflowError 和 OutOfMemoryError。

4. Java 堆 - 線程共享、最大塊

  • 核心職責:存放對象實例,幾乎所有對象在這裡分配。
  • GC 主戰場:又稱「GC 堆」,分代收集:新生代 + 老年代;新生代再分 Eden、From Survivor、To Survivor。
  • 分配優化:TLAB (Thread Local Allocation Buffer) 為線程私有分配緩衝區。
  • 物理不連續、邏輯連續即可。

5. 方法區 - 線程共享、非堆

  • 存儲內容:類信息、常量、靜態變量、即時編譯器編譯後代碼。
  • 規範寬鬆:可不連續、可固定/可擴展、可不實現 GC。
  • GC 行為少:主要回收常量池、卸載無用類。
  • 異常:內存分配不足拋出 OutOfMemoryError。
  • JDK 8+:元空間取代永久代,使用本地內存。

6. 運行時常量池 - 方法區一部分

  • Class 文件常量池(字面量、符號引用)加載後進入此區。
  • 動態性:運行期可新增常量(如 String.intern())。
  • 無法申請內存拋出 OutOfMemoryError。

7. 直接內存 - 非規範定義、但常用

  • NIO DirectByteBuffer 通過 Unsafe.allocateMemory 分配堆外內存。
  • 不受堆大小限制,但受本機總內存限制;頻繁使用易導致 OutOfMemoryError。

總結對照表

區域線程共享主要異常核心職能
程序計數器私有無字節碼行號指示
Java 棧私有StackOverflowError / OOM方法調用幀管理
本地方法棧私有StackOverflowError / OOMNative 方法支持
Java 堆共享OOM對象實例分配、GC
方法區共享OOM類元數據、常量、靜態字段
運行時常量池共享OOM符號引用、字面量、動態常量
直接內存共享OOMNIO 堆外分配、零拷貝

掌握此表,JVM 內存故障排查將有的放矢。

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