Java堆空間Vs棧內存

以前我寫了幾篇有關Java垃圾收集的文章以後,我收到了不少電子郵件,請求解釋Java堆空間Java棧內存Java中的內存分配以及它們之間的區別。
java-heap-space-stack.jpgjava

您可能在Java,Java EE書籍和教程中看到不少有關堆和變量內存的參考,可是幾乎沒有就程序而言徹底解釋堆和棧的內存分配的。程序員

Java堆空間

Java運行時使用Java堆空間爲對象和JRE類分配內存。每當咱們建立任何對象時,它老是在堆空間中建立。面試

垃圾回收在堆內存上運行以釋放沒有任何引用的對象使用的內存。在堆空間中建立的任何對象都具備訪問權限,而且能夠從應用程序的任何位置進行引用。算法

Java棧內存

Java Stack內存用於執行線程。它們包含短時間的方法特定值,以及從該方法引用的對堆中其餘對象的引用。spa

每當調用方法時,都會在磁盤存儲中建立一個新塊,以容納該方法的本地原始值並引用該方法中的其餘對象。線程

方法結束後,該塊將當即當即變爲未使用狀態,用做下一個方法使用。code

與堆內存分配,棧內存的大小要小一點。視頻

Java程序中的堆空間和棧內存分配

讓咱們用一個簡單的程序來了解堆和交替的內存使用狀況。對象

package com.journaldev.test;

public class Memory {

    public static void main(String[] args) { // Line 1
        int i=1; // Line 2
        Object obj = new Object(); // Line 3
        Memory mem = new Memory(); // 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-Heap-Stack-Memory.pngblog

讓咱們看一下程序的執行步驟。

  • 一旦運行程序,它將全部運行時類加載到堆空間中。在第1行找到main()方法後,Java Runtime建立的堆內存將被main()線程中方法使用。
  • 咱們在第2行建立原始局部變量,所以將其建立並存儲在main()方法的棧內存中。
  • 因爲咱們在第3行中建立了一個對象,所以將在堆內存中建立該對象,而且棧內存塊包含該對象的引用。在第4行中建立內存對象時,也會發生相似的過程。
  • 如今,當咱們在第5行調用foo()方法時,將在棧內存頂部建立一個塊,以供foo()方法使用。因爲Java是按值傳遞的,所以在第6行的foo()變量中中建立了對Object的新引用。
  • 在第7行建立一個字符串,該字符串進入堆空間的「字符串池」,並在foo()最小空間中建立引用。
  • foo()方法在第8行終止,這時分配給中foo()的棧內存塊被釋放。
  • 在第9行中main()方法終止,併爲main()方法建立的棧內存被銷燬。程序同時此行結束,所以Java Runtime釋放了全部內存並結束了程序的執行。

Java堆空間和棧內存之間的區別

根據以上解釋,咱們能夠輕鬆得出如下堆空間和棧內存的區別。

  1. 堆內存由應用程序的全部部分使用,而堆棧內存僅由一個執行線程使用。
  2. 在內存中建立對象時,它始終存儲在堆空間中,並存儲到包含該對象的引用中。內存僅包含本地原始變量和堆空間中對象的引用變量。
  3. 堆中存儲的對象能夠分區訪問,而其餘線程則不能訪問分區內存。
  4. 堆棧中的內存管理是之後進先出(LIFO)的方式完成的,而堆內存中的內存管理更復雜,由於它是全局使用的。
  5. 棧內存是短暫的,而堆空間是從應用程序執行的開始一直到結束。
  6. 咱們可使用-Xms-Xmx JVM選項來定義堆空間的初始值和最大值。咱們可使用-Xss定義棧內存的大小。
  7. 當棧內存已滿時,Java運行時將java.lang.StackOverFlowError引起,而若是堆內存已滿,則將引起java.lang.OutOfMemoryError: Java Heap Space錯誤。
  8. 棧內存相比於堆空間是很是小的。​因爲LIFO的簡單性,與堆空間相比,棧內存很是快。

就Java應用程序而言,這就是Java堆空間與棧內存的所有,我但願它能在執行任何Java程序時消除您對內存分配的疑問。


「不積跬步,無以致千里」,但願將來的你能:有夢爲馬 隨處可棲!加油,少年!

關注公衆號:「Java 知己」,天天更新Java知識哦,期待你的到來!

  • 發送「Group」,與 10 萬程序員一塊兒進步。
  • 發送「面試」,領取BATJ面試資料、面試視頻攻略。
  • 發送「玩轉算法」,領取《玩轉算法》系列視頻教程。
  • 千萬不要發送「1024」...
    每日福利
相關文章
相關標籤/搜索