資源描述:
《《java的內(nèi)存機(jī)制》word版》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、1.Java的內(nèi)存機(jī)制 Java把內(nèi)存劃分成兩種:一種是棧內(nèi)存,另一種是堆內(nèi)存。在函數(shù)中定義的一些基本類型的變量和對(duì)象的引用變量都是在函數(shù)的棧內(nèi)存中分配,當(dāng)在一段代碼塊定義一個(gè)變量時(shí),Java就在棧中為這個(gè)變量分配內(nèi)存空間,當(dāng)超過變量的作用域后(比如,在函數(shù)A中調(diào)用函數(shù)B,在函數(shù)B中定義變量a,變量a的作用域只是函數(shù)B,在函數(shù)B運(yùn)行完以后,變量a會(huì)自動(dòng)被銷毀。分配給它的內(nèi)存會(huì)被回收),Java會(huì)自動(dòng)釋放掉為該變量分配的內(nèi)存空間,該內(nèi)存空間可以立即被另作它用?! 《褍?nèi)存用來存放由new創(chuàng)建的對(duì)象和數(shù)組,在堆中分配的內(nèi)存,由Java虛擬機(jī)的自
2、動(dòng)垃圾回收器來管理。在堆中產(chǎn)生了一個(gè)數(shù)組或者對(duì)象之后,還可以在棧中定義一個(gè)特殊的變量,讓棧中的這個(gè)變量的取值等于數(shù)組或?qū)ο笤诙褍?nèi)存中的首地址,棧中的這個(gè)變量就成了數(shù)組或?qū)ο蟮囊米兞?,以后就可以在程序中使用棧中的引用變量來訪問堆中的數(shù)組或者對(duì)象,引用變量就相當(dāng)于是為數(shù)組或者對(duì)象起的一個(gè)名稱。引用變量是普通的變量,定義時(shí)在棧中分配,引用變量在程序運(yùn)行到其作用域之外后被釋放。而數(shù)組和對(duì)象本身在堆中分配,即使程序運(yùn)行到使用new產(chǎn)生數(shù)組或者對(duì)象的語句所在的代碼塊之外,數(shù)組和對(duì)象本身占據(jù)的內(nèi)存不會(huì)被釋放,數(shù)組和對(duì)象在沒有引用變量指向它的時(shí)候,才變
3、為垃圾,不能在被使用,但仍然占據(jù)內(nèi)存空間不放,在隨后的一個(gè)不確定的時(shí)間被垃圾回收器收走(釋放掉)。這也是Java比較占內(nèi)存的原因,實(shí)際上,棧中的變量指向堆內(nèi)存中的變量,這就是Java中的指針!代碼實(shí)例Test01:?jiǎn)蝹€(gè)對(duì)象創(chuàng)建·ViewCode·classPerson{·Stringname;·intage;·publicvoidtell(){·System.out.println("姓名:"+name+"年齡"+age);·}·}··publicclassTest01{·publicstaticvoidmain(String[]args
4、){·Personper=newPerson();·}·}在上述程序中實(shí)例化了一個(gè)對(duì)象per,在實(shí)例化對(duì)象的過程中需要在內(nèi)存中開辟空間,這其中就包括棧內(nèi)存和對(duì)內(nèi)存。具體的內(nèi)存分配如下圖所示:我們可以從上圖中發(fā)現(xiàn),對(duì)象名稱per被保存在了棧內(nèi)存中(更加準(zhǔn)確的說法是,在棧內(nèi)存中保存的是堆內(nèi)存空間的訪問地址),而對(duì)象的具體內(nèi)容,比如屬性name和age,被保存在了堆內(nèi)存中。因?yàn)閜er對(duì)象只是被實(shí)例化,還沒有具體被賦值,所以都是默認(rèn)值。字符串的默認(rèn)值為null,int類型的默認(rèn)值為0。前面也已經(jīng)提到,堆內(nèi)存空間必須使用new關(guān)鍵字才能開辟。代碼實(shí)
5、例Test02:多個(gè)對(duì)象創(chuàng)建·ViewCode·classPerson{Stringname;intage;publicvoidtell(){System.out.println("姓名:"+name+",年齡:"+age);}}publicclassTest02{publicstaticvoidmain(String[]args){Personper1=newPerson();Personper2=newPerson();per1.name="張三";per1.age=30;per2.name="李四";per2.age=33;per1
6、.tell();per2.tell();}}··關(guān)鍵概念:類跟數(shù)組一樣,都是屬于引用類型,引用類型就是指一堆對(duì)內(nèi)存可以同時(shí)被多個(gè)棧內(nèi)存指向。下面來看一下引用傳遞的簡(jiǎn)單實(shí)例。代碼實(shí)例Test03:對(duì)象引用傳遞1ViewCodeclassPerson{Stringname;intage;publicvoidtell(){System.out.println("姓名:"+name+",年齡:"+age);}}publicclassTest03{publicstaticvoidmain(String[]args){Personper1=newPe
7、rson();Personper2=per1;per1.name="張三";per1.age=30;per2.age=33;per1.tell();per2.tell();}}程序運(yùn)行結(jié)果為:姓名:張三,年齡:33姓名:張三,年齡:33從程序的運(yùn)行結(jié)果可以發(fā)現(xiàn),兩個(gè)對(duì)象輸出的內(nèi)容一樣,實(shí)際上所謂的引用傳遞,就是將一個(gè)堆內(nèi)存空間的使用權(quán)交個(gè)多個(gè)棧內(nèi)存空間,每個(gè)棧內(nèi)存空間都可以修改堆內(nèi)存空間的內(nèi)容,此程序的內(nèi)存分配圖如下所示:注意:上述實(shí)例中對(duì)象per2沒有堆內(nèi)存空間,這是因?yàn)閷?duì)象per2只進(jìn)行了聲明操作,也沒有進(jìn)行實(shí)例化操作。只有使用new
8、關(guān)鍵字實(shí)例化以后才會(huì)有對(duì)內(nèi)存空間。代碼實(shí)例Test04:對(duì)象引用傳遞2·ViewCode·classPerson{Stringname;intage;publicvoidtell(){Syst