更新時間:2022-07-07 12:00:28 來源:動力節(jié)點 瀏覽1684次
Java 應(yīng)用程序在計算機(jī)的RAM中編譯和執(zhí)行。每個應(yīng)用程序都分配了一定數(shù)量的內(nèi)存。在 RAM 中分配的內(nèi)存稱為應(yīng)用程序內(nèi)存。數(shù)據(jù)和代碼存儲在這里。分配給 Java 進(jìn)程的內(nèi)存量取決于多個因素,例如Java 運行時環(huán)境 (JRE)、操作系統(tǒng)、處理器等。JVM 將分配給進(jìn)程的內(nèi)存分為五個部分:Java堆棧、堆、類/方法區(qū)、程序計數(shù)器寄存器和本機(jī)方法堆棧。在本文中,動力節(jié)點小編將對堆棧和堆內(nèi)存進(jìn)行介紹。
堆棧內(nèi)存是為進(jìn)程分配的空間,用于存儲所有函數(shù)調(diào)用、原始數(shù)據(jù)類型(如 int、double 等)以及函數(shù)的局部變量和引用變量。堆棧內(nèi)存始終以后進(jìn)先出 (LIFO)方式訪問。在堆棧內(nèi)存中,為每個執(zhí)行的方法創(chuàng)建一個新的內(nèi)存塊。方法內(nèi)的所有原始變量和對對象的引用都存儲在此內(nèi)存塊中。當(dāng)方法完成執(zhí)行時,內(nèi)存塊從堆棧內(nèi)存中清除,堆棧內(nèi)存可供使用。只要創(chuàng)建它們的函數(shù)正在運行,堆棧中的值就存在。堆棧內(nèi)存的大小是固定的,一旦創(chuàng)建就不能增長或縮小。
下面是一個簡單的 Java 程序,它包含三個方法main、addOne和addTwo。當(dāng)這個程序執(zhí)行時,我們將看到堆棧使用的逐步解釋。
public class Main {
public static int addOne(int input) {
return input + 1;
}
public static int addTwo(int input) {
return input + 2;
}
public static void main(String[] args) {
int x = 0;
x = addOne(x);
x = addTwo(x);
}
}
1.程序執(zhí)行時,JVM首先執(zhí)行main方法。調(diào)用 main 方法時,會在堆棧中為其分配一個塊。方法中的變量被創(chuàng)建、賦值,然后存儲在塊中。
2.當(dāng)從 main 方法調(diào)用addOne方法時,會在堆棧中分配一個新塊。該方法的變量被創(chuàng)建并存儲在塊中。方法執(zhí)行完成后,將值返回給調(diào)用方法(這里是主方法),并清除塊。
3.同樣,當(dāng)調(diào)用addTwo方法時,會為其分配一個新塊,并創(chuàng)建和存儲變量。當(dāng)方法完成執(zhí)行時,將值返回給調(diào)用方法,并清除塊。
4.最后,main方法完成其執(zhí)行,并且從堆棧中清除該塊。
堆內(nèi)存用于存儲在 Java 程序執(zhí)行期間創(chuàng)建的對象。對創(chuàng)建的對象的引用存儲在堆棧內(nèi)存中。堆遵循動態(tài)內(nèi)存分配(內(nèi)存在執(zhí)行或運行時分配)并提供隨機(jī)訪問,與堆棧不同,堆棧遵循后進(jìn)先出 (LIFO) 順序。與堆棧相比,堆內(nèi)存的大小很大。堆內(nèi)存中未使用的對象由垃圾收集器自動清除。JVM堆內(nèi)存可以分為三部分:
新一代或年輕一代
老一代或老一代
永久代
新一代或年輕一代
年輕代是分配所有新創(chuàng)建對象的地方。新一代依次有 3 個部分,Eden、Survivor1和Survivor2。所有新創(chuàng)建的對象都分配在伊甸園空間中。當(dāng) Eden 已滿時,會發(fā)生一次次要的垃圾回收,并將活動對象移至Survivor1,然后移至Survivor2. Survivor1 和 Survivor2 包含在次要垃圾收集中幸存下來的對象。在 Eden、Survivor1 和 Survivor2 中幸存下來的對象將被移至終身代。在年老代中,垃圾收集的頻率較低,因此使用 Survivor1 和 Survivor2 空間來確保只有長期存活的對象才會被移動到年老代。
老一代或老一代
年齡是為年輕代分配的對象設(shè)置的。當(dāng)達(dá)到那個年齡時,那些活著的對象被移動到老年代。一般來說,長期存活的對象存儲在老年代。主要垃圾收集在老年代運行以收集死對象。
永久代
JVM 使用永久代來存儲有關(guān)類和方法的元數(shù)據(jù)。JVM 還將 Java 標(biāo)準(zhǔn)庫存儲在永久代中。該空間作為完整垃圾回收的一部分進(jìn)行清理。
import java.util.ArrayList;
import java.util.List;
public class HeapMemory {
public static void main(String[] args) {
int x = 10;
List < Integer > list = new ArrayList < > ();
list.add(1);
list.add(2);
list.add(3);
}
}
在上面的例子中,變量x分配在堆棧中,而對象列表分配在堆中。只有對列表對象的引用存儲在堆棧中。
相關(guān)閱讀
初級 202925
初級 203221
初級 202629
初級 203743