明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

對于垃圾回收的一些知識

[摘要]為什么要進(jìn)行垃圾回收?因?yàn)镴VM本身就實(shí)現(xiàn)內(nèi)存堆里的,它不可能有象C++的自動變量(臨時(shí)變量),所以所有的對象都要被會收.我們先來看一下C++:ClassType varname;//自動變量,在內(nèi)存的棧中創(chuàng)建,隨作用域的消失而自動消失. ClassType varname = new Class...
為什么要進(jìn)行垃圾回收?
因?yàn)镴VM本身就實(shí)現(xiàn)內(nèi)存堆里的,它不可能有象C++的自動變量(臨時(shí)變量),所以所有的對象都要被會收.我們先來看一下C++:

ClassType varname;//自動變量,在內(nèi)存的棧中創(chuàng)建,隨作用域的消失而自動消失.
ClassType varname = new ClassType();//在內(nèi)存堆中創(chuàng)建,要程序員手工釋放,如:
delete varname;相當(dāng)于C中的free


由于JVM本身就是在內(nèi)存堆中實(shí)現(xiàn),所以它不可能創(chuàng)建自動變量,所有的對象都有手工釋放,這個(gè)\\"手工"是指要程序?qū)崿F(xiàn),并不一定非要程序員編程,JVM自己就實(shí)現(xiàn)了"常規(guī)\\"對象的釋放,這就是JVM的垃圾回收器.

但對于非"常規(guī)\\"的對象比如直接或間接調(diào)用本地資源.(有人把圖象擦除認(rèn)為不是本地方法調(diào)用,其實(shí)它只是AWT在間接調(diào)用本地方法而已),就是程序員自己編程來釋放資源.

一個(gè)對象是如何被標(biāo)記垃圾(可回收對象)?以前有些實(shí)現(xiàn)采用"引用計(jì)數(shù)",就是一個(gè)對象在被引用的時(shí)候,引用計(jì)數(shù)加1,當(dāng)引用句柄消失時(shí)引用計(jì)數(shù)減速1,當(dāng)引用計(jì)數(shù)為0,就可被回收了.

那有人說剛new的對象不也被回收了嗎?

一個(gè)對象的生存期分為新生代,舊生代,新生代又分為Eden 和兩片生存空間其中保證有一片空間在任何時(shí)間是空的,對象剛被new的時(shí)候在Eden 中,垃圾回收器不會對Eden中對象回收,只有Eden中對象滿的時(shí)候,被復(fù)制到下一片生存空間.當(dāng)生存空間滿的時(shí)候,才會發(fā)生一次小回收.當(dāng)對象在生存空間太久達(dá)到一個(gè)\\"老化"的值時(shí)就被復(fù)制到了舊生代,舊生代滿的時(shí)候就發(fā)生大回收了.

但java并不是采用引用計(jì)數(shù)來標(biāo)記一個(gè)對象是否可以回收的.因?yàn)镴AVA中對象很可能被直接或間接循環(huán)引用,就是對象A中引用到對象B的一個(gè)屬性,而對象B又引用了A中一個(gè)屬性,這樣可能造成引用記數(shù)永遠(yuǎn)不會為0.

JAVA中是采用"由根遍歷\\"來標(biāo)記對象,就是從句柄開始對一個(gè)句柄引用的對象進(jìn)行查找,然后對這個(gè)對象引用的對象再進(jìn)行查找,這樣遞歸好象從樹根往沿枝條找到葉子,如果一個(gè)對象沒有被這樣查找到說明它已經(jīng)沒有對象對它引用了.

如何釋放非JAVA對象?我們已經(jīng)說過常規(guī)的JAVA對象會被JVM的垃圾回收器來回收,但對于本地資源(一般來說本地方法大都調(diào)用了本地資源),就要我們手工釋放了.


一般來說我們可以在finalize() 中定義釋放本地資源的代碼,但是這個(gè)方法不是肯定會被執(zhí)行的,finalize() 不是在對象退出的時(shí)候運(yùn)行,而是在對象被作為垃圾回收時(shí)才調(diào)用.有可能JVM一直不需要回收,所以這個(gè)方法就一直不會被調(diào)用,同樣如果要求對象在退出前一定要稍許對象,你一定要把釋放對象的代碼寫在try{}finally{}的finally塊中,這就是我再三強(qiáng)調(diào)釋放數(shù)據(jù)數(shù)連結(jié)一定要寫在這兒的原因,在java1.1中還有個(gè)方法是System.runFinalizersOnExit(),但它不如finally來得更有效.

同樣System.gc()方法并不能保證垃圾回收的發(fā)生,它只是"建議\\",而垃圾回到到底什么時(shí)候發(fā)生?小回收是生存空間滿,大回收是舊生代滿,這只是前提.因?yàn)槔厥帐堑蛢?yōu)先級的方式運(yùn)行,只有當(dāng)其他線程都掛起等待內(nèi)存釋放的情況出現(xiàn)時(shí),它才開始釋放對象的內(nèi)存.




相關(guān)文章