不少人在Java的書籍中看到過不少關於堆和棧內存的教程以及參考說明, 可是很難解釋什麼是程序的堆內存以及棧內存java
一: Java 堆內存空間jvm
Java程序運行時使用java Heap 內存爲對象以及JRE類分配內存, 不論咱們在什麼時候建立何種類型的對象, 他老是在堆內存中建立的函數
Java 垃圾收集器運行在堆內容空間, 釋放那些沒有任何引用的對象所使用的內存。 在堆內存空間建立的任何對象都具備全局訪問權限, 而且能夠從程序的任何位置引用this
二: Java 棧內存空間spa
Java 棧內存空間用於執行線程, 棧內存始終遵循LIFO(Last-in-first-out) 順序, 每當一個方法被執行, 會在棧內存中建立一個新的block 用於保存在函數中定義的基本數據類型變量以及對象的引用變量線程
當方法結束時, this block 改變它的狀態爲未使用而且可用於執行下一個方法code
堆內存大小與堆內存相比很是少。cdn
三: Java程序中的堆和堆棧內存對象
經過一個簡單的程序來理解堆 棧內存的使用狀況blog
/** * Created by huanjulu on 12/10/17. */
public class HeapStackTestMemory {
public static void main(String[] args) { //Line 1
int i = 1; //Line 2
Object obj = new Object(); //Line 3
HeapStackTestMemory mem = new HeapStackTestMemory(); //Line 4
mem.foo(obj); //Line 5
} //Line 9
private void foo(Object param) { //Line 6
String str = param.toString(); //Line 7
System.out.println(str);
} //Line 8
}複製代碼
參考上面的java 程序, 下圖顯示了stack Heap 內存空間的使用狀況
咱們來看看執行程序的步驟。
三: Java Heap Difference with Stack Memory Space
基於上述的說明, 能夠很容易的總結出堆棧內存的如下差別
1, 堆內存屬於java 應用程序所使用, 棧內存屬於線程所私有的, 它的生命週期與線程相同2, 不論什麼時候建立一個對象, 它老是存儲在堆內存空間 而且棧內存空間包含對它的引用 . 棧內存空間只包含方法原始數據類型局部變量以及堆空間中對象的引用變量3, 在堆中的對象能夠全局訪問, 棧內存空間屬於線程所私有4, jvm 棧內存結構管理較爲簡單, 遵循LIFO 的原則, 堆空間內存管理較爲複雜 , 細分爲:新生代和老年代 etc..5, 棧內存生命週期短暫, 而堆內存伴隨整個用用程序的生命週期6, 兩者拋出異常的方式, 若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError異常, 堆內存拋出OutOfMemoryError異常