JAVA中的棧和堆

轉:http://www.javashuo.com/article/p-hrhkylxv-ke.htmlhtml

JAVA在程序運行時,在內存中劃分5片空間進行數據的存儲。分別是:1:寄存器。2:本地方法區。3:方法區。4:棧。5:堆。程序員

基本,棧stack和堆heap這兩個概念很重要,不瞭解清楚,後面就不用學了。數組

如下是這幾天棧和堆的學習記錄和心得。得些記錄下來。之後有學到新的,會慢慢補充。函數

 

1、先說一下最基本的要點學習

基本數據類型、局部變量都是存放在棧內存中的,用完就消失。
new建立的實例化對象及數組,是存放在堆內存中的,用完以後靠垃圾回收機制不按期自動消除。3d

 

 

2、先明確以上兩點,如下示例就比較好理解了htm


示例1對象

main()
  int x=1;
show ()
  int x=2blog

主函數main()中定義變量int x=1,show()函數中定義變量int x=1。最後show()函數執行完畢。內存


以上程序執行步驟:

第1步——main()函數是程序入口,JVM先執行,在棧內存中開闢一個空間,存放int類型變量x,同時附值1。
第2步——JVM執行show()函數,在棧內存中又開闢一個新的空間,存放int類型變量x,同時附值2。
     此時main空間與show空間並存,同時運行,互不影響。
第3步——show()執行完畢,變量x當即釋放,空間消失。可是main()函數空間仍存在,main中的變量x仍然存在,不受影響。

示意圖以下:

 

——————————————————————————————————————————————————————————————————————

示例2

main()
  int[] x=new int[3];
  x[0]=20

主函數main()中定義數組x,元素類型int,元素個數3。

以上程序執行步驟
第1步——執行int[] x=new int[3];
  隱藏如下幾分支
  JVM執行main()函數,在棧內存中開闢一個空間,存放x變量(x變量是局部變量)。
  同時,在堆內存中也開闢一個空間,存放new int[3]數組,堆內存會自動內存首地址值,如0x0045。
  數組在棧內存中的地址值,會附給x,這樣x也有地址值。因此,x就指向(引用)了這個數組。此時,全部元素均未附值,但都有默認初始化值0。

第2步——執行x[0]=20
  即在堆內存中將20附給[0]這個數組元素。這樣,數組的三個元素值分別爲20,0,0

示圖以下:

——————————————————————————————————————————————————————————————————————


示例3
main()
  int[] x=new int[3];
  x[0]=20
  x=null;

以上步驟執行步驟
第一、2步——與示例2徹底同樣,略。

第3步——執行x=null;
  null表示空值,即x的引用數組內存地址0x0045被刪除了,則再也不指向棧內存中的數組。此時,堆中的數組再也不被x使用了,即被視爲垃圾,JVM會啓動垃圾回收機制,不定時自動刪除。

示圖以下

——————————————————————————————————————————————————————————————————

示例4
main()
  int[] x=new int[3];
  int[] y=x;
  y[1]=100
  x=null;

以上步驟執行步驟

第1步——與示例2第1步一致,略。
第2步——執行int[] y=x,
  在棧內存定義了新的數組變量內存y,同時將x的值0x0045附給了y。因此,y也指向了堆內存中的同一個數組。
第3步——執行y[1]=100
  即在堆內存中將20附給[0]這個數組元素。這樣,數組的三個元素值分別爲0,100,0
第4步——執行x=null
  則變量x再也不指向棧內存中的數組了。可是,變量y仍然指向,因此數組不消失。

示圖以下

——————————————————————————————————————————————————————————————————

示例5

Car c=new Car;
c.color="blue";
Car c1=new Car;
c1.num=5;

 雖然是個對象都引用new Car,可是是兩個不一樣的對象。每一次new,都產生不一樣的實體

 

——————————————————————————————————————————————————————————————————

示例6

Car c=new Car;
c.num=5;
Car c1=c;
c1.color="green";
c.run();

Car c1=c,這句話至關於將對象複製一份出來,兩個對象的內存地址值同樣。因此指向同一個實體,對c1的屬性修改,至關於c的屬性也改了。

 

 

3、棧和堆的特色

棧:

函數中定義的基本類型變量,對象的引用變量都在函數的棧內存中分配。
棧內存特色,數數據一執行完畢,變量會當即釋放,節約內存空間。
棧內存中的數據,沒有默認初始化值,須要手動設置。

 

堆:

堆內存用來存放new建立的對象和數組。
堆內存中全部的實體都有內存地址值。
堆內存中的實體是用來封裝數據的,這些數據都有默認初始化值。
堆內存中的實體再也不被指向時,JVM啓動垃圾回收機制,自動清除,這也是JAVA優於C++的表現之一(C++中須要程序員手動清除)。

 

注:

什麼是局部變量:定義在函數中的變量、定義在函數中的參數上的變量、定義在for循環內部的變量

相關文章
相關標籤/搜索