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

Java 程序運行時內存分配深度解析:堆、棧、方法區與對象訪問機制

     編輯:Java 相關知識

JVM 內存三大區域

區域存儲內容線程共享性生命週期
堆所有對象實例、數組對象全局共享GC 管理,進程存續
棧基本類型變量、對象引用、方法幀、操作數棧線程私有隨線程/方法創建銷毀
方法區類元數據、常量池、static 字段、JIT 編譯代碼全局共享進程存續(元空間)

對象創建與訪問全過程

Sample test1 = new Sample("測試1");

步驟拆解

  1. 類加載:JVM 在方法區查找 Sample 類元數據,無則加載(讀取 .class → 解析 → 存入方法區)
  2. 堆分配:在堆中劃分內存區域,存儲對象實例數據(字段值)+ 指向方法區類元數據的指針(Klass Pointer)
  3. 棧分配:當前線程棧幀局部變量表槽位存儲引用變量 test1,指向堆中對象地址
  4. 初始化:執行構造器,字段賦值(基本類型默認值 → 顯式賦值 → 構造器代碼)
  5. 方法調用:test1.printName() → 棧幀入棧 → 根據引用定位堆對象 → 根據 Klass Pointer 定位方法區字節碼 → 執行

基本類型 vs 引用類型存儲差異

基本類型(8 種)

  • 字面值直接存儲在棧(局部變量)或堆(對象字段)
  • 大小固定、生命週期可知、訪問速度最快
  • 值語義:int a=3; int b=3; 棧中共享字面值 3;a=4 不影響 b

包裝類/引用類型

  • 對象實體在堆,引用在棧
  • Integer a=3; Integer b=3; 自動裝箱可能複用緩存池(-128~127),但 new Integer(3) 必創新對象
  • String 特殊:字面值進常量池,new String() 強制堆分配

經典案例圖解

public class AppMain {
    public static void main(String[] args) {
        Sample test1 = new Sample("測試1");
        Sample test2 = new Sample("測試2");
        test1.printName();
        test2.printName();
    }
}
class Sample {
    private String name;
    public Sample(String name) { this.name = name; }
    public void printName() { System.out.println(name); }
}

內存圖景

  • 方法區:AppMain.class、Sample.class、字符串常量 "測試1"、"測試2"
  • 堆:Sample#1 (name→"測試1")、Sample#2 (name→"測試2")
  • 主線程棧:main() 幀 → 局部變量 test1→Sample#1, test2→Sample#2
  • printName() 調用:新建棧幀,this 指向對應 Sample 實例

棧與堆性能對比

維度棧堆
分配速度指針移動,極快TLAB/指針碰撞/空闲列表,較慢
訪問速度直接偏移量,最快引用解引用,間接訪問
靈活性大小/生命週期必須編譯期確定動態分配,GC 自動回收
共享性線程私有,不可共享全局共享,需同步控制

String 對象特殊性(預告下篇重點)

  • 字面值進常量池(方法區/堆,版本差異),intern() 手動入池
  • + 拼接編譯期優化為 StringBuilder,運行期 new StringBuilder().append().toString()
  • 不可變性導致頻繁創建臨時對象,性能敏感場景用 StringBuilder/StringBuffer

總結

Java 內存模型清晰分工:方法區存類、堆存對象、棧存引用與基本類型。理解「引用在棧、對象在堆」是排查 OOM、內存洩漏、逃逸分析的基礎。現代 JVM (JDK 8+) 永久代→元空間,字符串常量池遷移至堆,但核心邏輯不變。建議配合 -XX:+PrintGCDetails、JVisualArth、Arthas 等工具實戰觀察。

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