????java在運(yùn)行程序時(shí)乌妙,在內(nèi)存中劃分了5片空間進(jìn)行數(shù)據(jù)的存儲(chǔ)。分別是:存儲(chǔ)器建钥、本地方法區(qū)藤韵、方法區(qū)、棧锦针、堆荠察。
在Java項(xiàng)目開(kāi)發(fā)中置蜀,掌握堆heap和棧stack的概念非常重要,相當(dāng)于地基的存在悉盆。
堆和棧的作用
基本數(shù)據(jù)類型盯荤、局部變量都是存放在棧中的,用完就會(huì)消失焕盟。new創(chuàng)建的實(shí)例化對(duì)象及數(shù)組是存放在堆內(nèi)存中的秋秤,用完之后靠垃圾回收機(jī)制(gc)不定期自動(dòng)清除。
換言之脚翘,引用存放在堆中灼卢,值在棧中。gc不定期回收堆中垃圾来农。
示例
public class Test {
public static void main(String[] args) {
int x=1;
? ? ? show();
? ? }
static void show(){
int x=2;
? ? }
}
運(yùn)行main方法鞋真;jvm具體執(zhí)行步驟是:
第1步——main()函數(shù)是程序入口,JVM先執(zhí)行沃于,在棧內(nèi)存中開(kāi)辟一個(gè)空間涩咖,存放int類型變量x,同時(shí)附值1繁莹。
第2步——JVM執(zhí)行show()函數(shù)檩互,在棧內(nèi)存中又開(kāi)辟一個(gè)新的空間,存放int類型變量x咨演,同時(shí)附值2闸昨。此時(shí)main空間與show空間并存,同時(shí)運(yùn)行薄风,互不影響饵较。
第3步——show()執(zhí)行完畢,變量x立即釋放遭赂,空間消失告抄。但是main()函數(shù)空間仍存在,main中的變量x仍然存在嵌牺,不受影響。
public class Test {
public static void main(String[] args) {
int[] x=new int[3];
? ? ? x[0]=20;
? ? }
}
以上程序執(zhí)行步驟
第1步——執(zhí)行int[] x=new int[3];
隱藏以下幾分支
JVM執(zhí)行main()函數(shù)龄糊,在棧內(nèi)存中開(kāi)辟一個(gè)空間逆粹,存放x變量(x變量是局部變量)。
同時(shí)炫惩,在堆內(nèi)存中也開(kāi)辟一個(gè)空間僻弹,存放new int[3]數(shù)組,堆內(nèi)存會(huì)自動(dòng)內(nèi)存首地址值他嚷,如0x0045蹋绽。
數(shù)組在棧內(nèi)存中的地址值芭毙,會(huì)附給x,這樣x也有地址值卸耘。所以退敦,x就指向(引用)了這個(gè)數(shù)組。此時(shí)蚣抗,所有元素均未附值侈百,但都有默認(rèn)初始化值0。
第2步——執(zhí)行x[0]=20
即在堆內(nèi)存中將20附給[0]這個(gè)數(shù)組元素翰铡。這樣钝域,數(shù)組的三個(gè)元素值分別為20,0,0
public class Test {
public static void main(String[] args) {
int[] x=new int[3];
? ? ? x[0]=20;
? ? ? x=null;
? ? }
}
以上步驟執(zhí)行步驟
第1、2步——與示例2完全一樣锭魔,略例证。
第3步——執(zhí)行x=null;
null表示空值,即x的引用數(shù)組內(nèi)存地址0x0045被刪除了迷捧,則不再指向棧內(nèi)存中的數(shù)組织咧。此時(shí),堆中的數(shù)組不再被x使用了党涕,即被視為垃圾烦感,JVM會(huì)啟動(dòng)垃圾回收機(jī)制,不定時(shí)自動(dòng)刪除膛堤。
public static void main(String[] args) {
int[] x=new int[3];
int[] y=x;
y[1]=100;
x=null;
}
以上步驟執(zhí)行步驟
第1步——與示例2第1步一致手趣,略。
第2步——執(zhí)行int[] y=x肥荔,
在棧內(nèi)存定義了新的數(shù)組變量?jī)?nèi)存y绿渣,同時(shí)將x的值0x0045附給了y。所以燕耿,y也指向了堆內(nèi)存中的同一個(gè)數(shù)組中符。
第3步——執(zhí)行y[1]=100
即在堆內(nèi)存中將100附給[0]這個(gè)數(shù)組元素。這樣誉帅,數(shù)組的三個(gè)元素值分別為0,100,0
第4步——執(zhí)行x=null
則變量x不再指向棧內(nèi)存中的數(shù)組了淀散。但是,變量y仍然指向蚜锨,所以數(shù)組不消失档插。
public class Test {
public static void main(String[] args) {
Car c=new Car();
? ? c.color="blue";
? ? Car c1=new Car();
? ? c1.num=1;
? ? }
}
class Car{
public Stringcolor;
? ? public? int num;
}
c 和c1是兩個(gè)不同的對(duì)象,每次new對(duì)象都會(huì)產(chǎn)生不同的實(shí)體亚再;
public class Test {
public static void main(String[] args) {
Car c=new Car();
? ? c.num=5;
? ? Car c1=c;
? ? c1.color="green";
? ? ? ? System.out.println(c.color);//green
? ? }
}
class Car{
public Stringcolor;
? ? public? int num;
}
Car c1=c朽色,這句話相當(dāng)于將對(duì)象復(fù)制一份出來(lái)盹廷,兩個(gè)對(duì)象的內(nèi)存地址值一樣特笋。所以指向同一個(gè)實(shí)體,對(duì)c1的屬性修改耘柱,相當(dāng)于c的屬性也改了。