Java內存分配

一般Java在內存分配時會涉及到以下區域:
  ◆寄存器:我們在程序中無法控制
  ◆棧:存放基本類型的數據和對象的引用,但對象本身不存放在棧中,而是存放在堆中(new 出來的對象)
  ◆堆:存放用new產生的數據
  ◆靜態域:存放在對象中用static定義的靜態成員
  ◆常量池:存放常量
  ◆非RAM存儲:硬盤等永久存儲空間

棧:方法中定義的一些基本類型的變量數據和對象(和形式參數)的引用變量都在棧內存中分配,棧內存中的局部變量隨着方法的消失而消失。存在棧中的數據可以共享

堆:存放由new創建的對象和數組,由GC管理。棧中定義引用變量,其取值等於數組或對象在堆內存中的首地址。引用變量在程序運行到其作用域之外後被釋放。而數組和對象不會,他們只有在沒有引用變量指向它的時候纔會被GC在適當時機回收。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class BirthDate { 
    private int day; 
    private int month; 
    private int year;     
    public BirthDate(int d, int m, int y) { 
        day = d;  
        month = m;  
        year = y; 
    } 
   
public class Test{ 
    public static void main(String args[]){ 
        int date = 9; 
        Test test = new Test();       
        test.change(date);  
        BirthDate d1= new BirthDate(7,7,1970);        
    }   
   
    public void change1(int i){ 
        i = 1234; 
    }
}

下面分析一下代碼執行時候的變化: 
1. main方法開始執行:int date = 9; date局部變量,基礎類型,引用和值都存在棧中。 
2. Test test = new Test(); test爲對象引用,存在棧中,對象(new Test())存在堆中。 
3. test.change(date); i爲局部變量,引用和值存在棧中。當方法change執行完成後,i就會從棧中消失。 
4. BirthDate d1= new BirthDate(7,7,1970);d1 爲對象引用,存在棧中,對象(new BirthDate())存在堆中,其中d,m,y爲局部變量存儲在棧中,且它們的類型爲基礎類型,因此它們的數據也存儲在棧中。 day,month,year爲成員變量,它們存儲在堆中(new BirthDate()裏面)。當BirthDate構造方法執行完之後,d,m,y將從棧中消失。
5.main方法執行完之後,date變量,test,d1引用將從棧中消失,new Test(),new BirthDate()將等待垃圾回收。

常量池:常量池指在編譯期被確定,並被保存在已編譯的.class文件中的數據。
除了包含代碼中所定義的各種基本類型和對象型的常量值(final)還包含一些以文本形式出現的符號引用,比如:
  ◆類和接口的全限定名;
  ◆字段的名稱和描述符;
  ◆方法的名稱和描述符;
String類型在編譯期已經創建好(直接用雙引號定義的)的就存儲在常量池中,如果是運行期(new出來的)才能確定的就存儲在堆中。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章