#暑期創作大賽#
JVM(Java虛拟機)運作時記憶體區域可以分為以下幾個部分:
方法區(Method Area):
用于存儲類的結構資訊,例如類的位元組碼、常量池、靜态變量、方法的位元組碼等。在JDK 8及之前,方法區被實作為永久代(Permanent Generation),而在JDK 8及以後的版本中,方法區被替換為元空間(Metaspace)。
示例:
public class MyClass {
// 靜态變量
public static int myStaticVar = 10;
// 靜态方法
public static void myStaticMethod() {
System.out.println("This is a static method.");
}
// 執行個體變量
public int myInstanceVar = 20;
// 執行個體方法
public void myInstanceMethod() {
System.out.println("This is an instance method.");
}
public static void main(String[] args) {
MyClass.myStaticMethod();
MyClass obj = new MyClass();
obj.myInstanceMethod();
}
}
在上面的示例中,靜态變量和靜态方法存儲在方法區中,而執行個體變量和執行個體方法則在堆中的對象執行個體中。
堆(Heap):
用于存儲對象執行個體。堆是JVM中最大的一塊記憶體區域,它是所有線程共享的。堆被分為新生代(Young Generation)和老年代(Old Generation)。新生代進一步被分為Eden區、Survivor區(通常有兩個)。
示例:
public class MyClass {
public static void main(String[] args) {
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
MyClass obj3 = new MyClass();
// 輸出對象的哈希碼,用于表示對象在記憶體中的位址
System.out.println(obj1);
System.out.println(obj2);
System.out.println(obj3);
}
}
在上面的示例中,通過new關鍵字建立了三個MyClass的對象執行個體。這些對象執行個體存儲在堆中,并且每個對象執行個體都有一個唯一的位址(即哈希碼)。
Eden區:
新建立的對象首先會被配置設定到Eden區。當Eden區滿時,觸發一次新生代的垃圾回收,存活的對象會被複制到Survivor區。
Survivor區:
存活的對象經過幾次垃圾回收後,會被移動到Survivor區。Survivor區主要用于存放新生代中存活的對象。當Survivor區滿時,存活的對象會被複制到另一個Survivor區,同時會清空目前Survivor區。
public class MyClass {
public static void main(String[] args) {
byte[] bytes1 = new byte[1024 * 1024];
byte[] bytes2 = new byte[1024 * 1024];
byte[] bytes3 = new byte[1024 * 1024];
// 輸出堆中三個數組的位址
System.out.println(bytes1);
System.out.println(bytes2);
System.out.println(bytes3);
}
}
在上面的示例中,通過建立三個大小為1MB的位元組數組,展示了堆記憶體中新生代的劃分。這些位元組數組首先會被配置設定到Eden區,當Eden區滿了之後,會觸發一次新生代的垃圾回收,存活的對象會被複制到Survivor區。下一次垃圾回收時,存活的對象會被複制到另一個Survivor區,并清空目前Survivor區。這個過程不斷重複,直到對象在Survivor區經過多次垃圾回收後仍然存活,它們會被晉升到老年代。
老年代:
經過多次垃圾回收後仍然存活的對象會被移動到老年代。老年代主要用于存放長期存活的對象。
棧(Stack):
每個線程在運作時都會建立一個棧。棧用于存儲方法調用的資訊、局部變量、方法參數等。每個方法在執行時都會建立一個棧幀,棧幀包含了方法的局部變量和操作數棧等資訊。棧是一個線程私有的記憶體區域。
本地方法棧(Native Method Stack):
類似于棧,但是用于執行本地方法(非Java代碼)。
PC寄存器(Program Counter Register):
存儲目前線程執行的位元組碼指令位址。
堆外記憶體(Off-heap Memory):
不在JVM堆中的記憶體,通常用于存儲大量的資料或與本地庫進行互動。