1. 程式人生 > 其它 >Java程式記憶體的簡單分析

Java程式記憶體的簡單分析

轉載於:https://www.cnblogs.com/huangminwen/p/5928315.html

這篇文章將簡單的說明下當我們執行Java程式時JVM(Java虛擬機器)的記憶體分配情況。

首先我們先來感觀的認識下幾個名詞:

  • 棧:一般來說,基本資料型別直接在棧中分配空間,區域性變數(在方法程式碼段中定義的變數)也在棧中直接分配空間,當局部變數所在方法執行完成之後該空間便立刻被JVM回收,還有一種是引用資料型別,即我們通常所說的需要用關鍵字new創建出來的物件所對應的引用也是在棧空間中,此時,JVM在棧空間中給物件引用分配了一個地址空間(相當於一個門牌號,通過這個門牌號就可以找到你家),在堆空間中給該引用的物件分配一個空間,棧空間中的地址引用指向了堆空間中的物件區(通過門牌號找住址);
  • 堆:一般用來存放用關鍵字new出來的資料。

接下來我們再通過一段程式來直觀感受下程式執行時JVM的記憶體情況,

package demo;

public class Student {
    private String name;
    private int age;

    public void study() {
        System.out.println("I love study!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        
this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package demo;

public class Student {
    private String name;
    private int age;

    public void study() {
        System.out.println("I love study!");
    }

    
public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

我們執行程式時,JVM會把Student類與StudentDemo類編譯完然後載入到JVM中一個叫方法區的地方,類的成員變數與成員方法也被載入到方法區中,此時記憶體模型如下

可以看到study方法右邊各有一個16進位制的標記,而name與age變數沒有,這是因為每個物件都有各自的成員變數,而類中的成員方法卻可以被每個物件所共用,為了節省記憶體空間,JVM為方法分配了該標記(也叫記憶體地址)便於每個new出來的物件查詢呼叫,接著JVM會自動尋找main方法,在棧中為main方法申請一個空間,這個過程也叫入棧,然後執行我們Student類中第5行程式碼

這時候,JVM在堆空間中分配一塊記憶體給Student物件,併為其分配一個記憶體地址(如果物件的成員變數沒有賦值,則JVM會為變數賦初始值),在棧中分配一塊記憶體空間用於指向堆空間中的Student物件區的記憶體地址,此時記憶體模型如下

接著看程式碼第8行與第9行

程式為student物件的成員變數賦值,JVM會根據student所指向的地址在堆記憶體中尋找Student類的變數,併為變數賦新的值

第12行

這時student物件呼叫study方法,JVM在棧空間中為study方法申請了一塊記憶體空間

study方法執行完後,立即釋放棧空間,程式碼第14行,

student2物件的引用指向了student所指向的地址

程式碼15與16行

為student2的變數賦值,由於student2與student指向了同一個地方,所以這時student物件中變數的值也被改變

到這,main方法中所有程式碼執行完畢,main方法所佔用的棧空間也被回收,而堆空間等待GC回收

程式碼執行結果如下:

null:0
John:23
I love study!
Jack:25
Jack:25

寫的較為簡單,僅作為知識記錄,歡迎指正!