Java 堆內存與棧內存異同(Java Heap Memory vs Stack Memory Difference)

1、Java 堆存儲空間

堆內存(堆存儲空間)會在Java運行時分配給對象(Object)或者JRE的類。只要咱們建立了一個對象,那麼在堆中確定會分配一塊存儲空間給這個對象。而咱們熟知的Java垃圾回收就是在堆存儲空間上進行的,用以釋放那些沒有任何引用指向自身的對象。任何在堆中分配的對象都有全局訪問權限,並且能夠從應用的任何地方被引用。堆內存用於存放由new建立的對象和數組。 2、Java 棧存儲空間 Java 棧存儲空間用來供線程執行時使用。棧空間中包含特別的變量如:短生命週期和指向其餘在堆中對象的引用。這裏棧存儲空間知足後進先出的順序。當一個函數被調用時,會在棧中分配一塊新的存儲空間,用來存放函數的基本數據(【Java心得總結一】Java基本類型和包裝類型解析)以及在函數中對其它對象的引用。一旦函數執行結束,存儲空間就會被釋放供下一個函數使用。在函數中定義的一些基本類型的變量和對象的引用變量都是在函數的棧內存中分配。java

3、舉例

Memory.java數組

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
 
}

下圖展現了堆棧存儲空間是如何存儲基本類型、對象以及指向變量的引用 輸入圖片說明函數

程序執行過程:線程

  1. 一旦咱們開始運行程序,它會將全部運行時類裝載入堆存儲空間。當程序運行至第一行main()函數,Java Runtime會爲主函數線程分配棧存儲空間。
  2. 咱們在第二行建立了基本數據類型,因此它會被存儲在主函數線程的棧存儲空間;
  3. 由於咱們在第三行建立了Object對象,它會在堆中被建立,而且棧空間中保存有指向它的引用。同理第四行建立Memory對象。
  4. 當咱們在main()主函數第五行調用foo()函數時,在棧空間頂部會分配一塊空間給foo()函數使用。由於Java是值傳遞(Java 爲值傳遞而不是引用傳遞),在foo函數第六行中會有一個新的引用被建立指向堆中的Object對象
  5. 在第7行建立了一個字符串,它會被放在堆空間的字符串池中(String Poll),並且在棧空間中會保存一個指向它的引用
  6. 在第8行foo函數執行完畢,此時其棧空間會被釋放
  7. 在第9行main函數執行完畢,棧中分配給main函數的空間會被釋放。同時程序也在這一行執行完畢,所以Java運行時(Java Runtime)會釋放全部內存空間而且終止程序的執行。
相關文章
相關標籤/搜索