轉: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循環內部的變量