Java 中的內存分配


Java 中的內存分配

Java 程序運行時,需要在內存中分配空間。為了提高運算效率,就對空間進行了不同區域的划分,因為每一片區域都有特定的處理數據方式和內存管理方式。

 

一、棧:儲存局部變量

  • 局部變量:在方法的定義中或者在方法聲明上的變量稱為局部變量。
  • 特點:棧內存的數據用完就釋放。

二、堆:儲存 new 出來的東西

  • 特點:
    • 每一個 new 出來的東西都有地址值;
    • 每個變量都有默認值 (byte, short, int, long 的默認值為 0;float, double 的默認值為 0.0;char 的默認值為 “\u0000”;boolean 的默認值為 false;引用類型為 null);
    • 使用完畢就變成垃圾,但是並沒有立即回收。會有垃圾回收器空閑的時候回收。

 

三、方法區:

一個對象的運行過程:

  1. 程序從 main 方法中進入;運行到 Phone p 時,在棧中開辟了一個空間;
  2. new Phone() 時,在隊中開了一個內存空間,此時會有一個內存值為 0x0001;此時會找到對應的 Phone 的 class 文件,發現有三個變量和三個方法,於是將三個成員變量放在了堆中,但是此時的值為默認值(具體默認值見上)。注意,在方法區里也有一個地址值,假設為 0x001,可以認為在堆中也有一個位置,在堆中的位置,可以找到方法區中相對應的方法;
  3. 繼續運行,p.brand = "三星";將三星賦值給 p.brand,通過棧中的 p 找到了堆中的 brand,此時的 null 值變為“三星”。剩下的類似;
  4. 當運行到 p.call("喬布斯") 時,通過棧中的 p 找到堆中存在的方法區的內存地址,從而指引到方法區中的 Phone.class 中的方法。從而將 call 方法加載到棧內存中,注意:當執行完畢后,call 方法就從棧內存中消失!剩余的如上。
  5. 最后,main 方法消失!

 

兩個對象的運行過程:

  1. 程序從 main() 方法進入,運行到 Phone p 時,棧內存中開內存空間;
  2. new Phone() 時,在隊中開了一個內存空間,內存值為 0x0001;此時會找到對應的 Phone 類,發現有三個變量,於是將三個成員變量放在了堆中,但是此時的值為默認值。又發現該類還存在方法,於是將該方法的內存值留在了堆中,在方法區里也有一個地址值,假設為 0x001,這個值與堆中的值相對應;
  3. 程序繼續運行,到 p.brand 時,進行了負值,同上;
  4. 當程序運行到 Phone p2 時;到 new Phone() 時,在堆內存中開辟了內存空間 0x0002,賦值給 Phone p2;
  5. 剩下跟一個對象的內存相同。

 

 

 

三個對象的運行過程:

  1. 基本流程跟前兩個無差別;
  2. 但是當運行到 Phone p3 時,在棧內存中分配了一個空間,然后將 p1 的內存賦值給了 p3,即此時 Phone p3 的內存是指向 0x0001 的;
  3. 繼續給變量賦值,會將原來已經賦值的變量給替換掉。

 

 

四、本地方法區(和系統相關)

五、寄存器(給 CPU 使用)

 

一個材料人跨行到互聯網的研究僧

希望大家能多多關注~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM