Java 虛擬機運行時數據區分為方法區、堆、虛擬機棧、本地方法棧、程序計數器。
方法區(Method Area):
[1] 存儲類信息、常量、靜態變量和即時編譯器(JIT)編譯后的代碼。
[2] 屬于線程共享區域,所有線程共享方法區內存
[3] 在 JDK8之前,HotSpot使用永久代(PermGen)來實現方法區,JDK8之后被元空間(Metaspace)取代,元空間使用的是本地內存(Native Memory)。
堆(Heap):
[1] 用于存放所有線程共享的對象和數組,是垃圾回收的主要區域。
虛擬機棧(JVM Stack):
[1] 每個線程創建一個棧,用來保存局部變量、操作數棧、動態鏈接、方法出口信息等
[2] 局部變量表中存儲的是基本數據類型(如int、float)以及對象引用。
[3] 棧是線程私有的,生命周期與線程相同。
本地方法棧(Native Method Stack):
[1] 為本地方法服務,使用JNI(Java Native Interface)調用的本地代碼在此區域分配內存。
[2] 和虛擬機棧類似,也是線程私有的。
程序計數器(Program Counter Register):
[1] 是一個小的內存區域,保存當前線程執行的字節碼指令的地址或行號。
[2] 每個線程都有一個獨立的程序計數器,屬于線程私有。
堆內存的進一步劃分
[1] Eden 區:新對象最初會被分配到 Eden 區,且 Eden 區較大,頻繁進行垃圾回收。
[2] Survivor 區:兩個Survivor 區 S0 和 S1 交替使用,新對象在 Eden 區經過一次垃圾回收后存放到其中一個 Survivor區,進一步存活的對象會移動到另一個 Survivor 區,最終晉升到老年代。
[3] 老年代:長生命周期對象經過多次垃圾回收后會被移到老年代,MaiorGC在老年代進行,頻率較低但耗時較長。