Java程序中也可能會發(fā)生內(nèi)存泄露的問題,但是Java中引入了垃圾回收機(jī)制。這里所說的垃圾就是那些泄露的內(nèi)存。
在Java語言中,沒有引用句柄指向的類對象最容易成為垃圾。產(chǎn)生垃圾的情況有很多,主要有以下3種:
(1) 超出對象的引用句柄的作用域時,這個引用句柄引用的對象就變成垃圾。
例:
{
Person p1 = new Person();
……
}
引用句柄p1的作用域是從定義到“}”處,執(zhí)行完這對大括號中的所有代碼后,產(chǎn)生的Person對象就會變成垃圾,因?yàn)橐眠@個對象的句柄p1已超過其作用域,p1已經(jīng)無效,Person對象不再被任何句柄引用了。
(2) 沒有超出對象的引用句柄的作用域時,給這個引用句柄賦值為空時,這個引用句柄引用的對象就變成垃圾。
例:
{
Person p1 = new Person();
…..
p1 = null;
….
}
在執(zhí)行完“p1=null;”后,即使句柄p1還沒有超出其作用域,仍然有效,但它已被賦值為空,不再指向任何對象,則這個Person對象不再被任何句柄引用,變成了垃圾。此后p1還可以指向其它Person對象,因?yàn)檫€沒有超出它的作用域。
(3) 創(chuàng)建匿名對象時,匿名對象用完以后即成垃圾。
例:
{
new Person(); //因?yàn)槭悄涿麑ο螅瑳]有引用句柄指向它,即為垃圾
new Person().print();
//當(dāng)運(yùn)行完匿名對象的print()方法,這個對象也變成了垃圾
……
}
因此,在程序中應(yīng)盡量少用匿名對象。
5. Java中的對象銷毀
Java語言沒有提供析構(gòu)函數(shù),要解決內(nèi)存泄露的問題,要銷毀不再被引用的對象,就要借助其它方法,因此Java提供了一種非常好的機(jī)制:垃圾回收機(jī)制,即Garbage Collector,簡稱GC。
在Java中,不再被引用的對象所占據(jù)的內(nèi)存由一個低優(yōu)先級的垃圾回收線程自動回收。這個線程是在我們程序的執(zhí)行過程中在后臺持續(xù)運(yùn)行的。在Java程序運(yùn)行過程中,一個垃圾回收器會不定時地被喚起檢查是否有不再被使用的對象,并釋放它們占用的內(nèi)存空間。垃圾回收器的回收無規(guī)律可循,可能在程序的運(yùn)行的過程中,一次也沒有啟動,也可能啟動很多次。因此,并不會因?yàn)槌绦虼a一產(chǎn)生垃圾,垃圾回收器就馬上被喚起而自動回收垃圾,很可能到程序結(jié)束時垃圾回收器都沒有啟動。所以垃圾回收器并不能完全避免內(nèi)存泄漏的問題。
正因?yàn)槔厥掌鲉拥臒o規(guī)律性,Java又提供了一種強(qiáng)制啟動垃圾回收器的方法:System.gc()方法。在程序中顯式地加入這個語句,就會強(qiáng)制啟動垃圾回收器。垃圾回收器啟動后,就會等待時機(jī)釋放不再被引用的對象所占據(jù)的內(nèi)存空間。但并不是一啟動垃圾回收器,它就馬上回收垃圾,如果這時有高優(yōu)先級的線程仍在運(yùn)行,回收垃圾的線程需要等待這個高優(yōu)先級的線程執(zhí)行完畢以后才可執(zhí)行。
另一方面,垃圾回收會給系統(tǒng)資源帶來額外的負(fù)擔(dān)和時空開銷。它被啟動的幾率越小,帶來的負(fù)擔(dān)的幾率就越小。因此,不提倡在程序代碼中加入大量的System.gc()語句。
正因?yàn)槔厥掌鞯淖詣踊厥展δ埽WC了Java開發(fā)的程序在長期運(yùn)行期間產(chǎn)生比較少的內(nèi)存泄露,提高了系統(tǒng)的性能,方便了用戶的使用。
結(jié)束語
在C++中,可能因?yàn)椴磺‘?dāng)?shù)厥褂胣ew和delete語句,而導(dǎo)致不能銷毀某些對象,造成內(nèi)存泄露,從而影響系統(tǒng)的性能;而Java提供了垃圾回收機(jī)制自動回收垃圾,銷毀不再使用的對象,使得內(nèi)存泄露的可能性變得很小。
posted on 2010-07-06 16:27
Werther 閱讀(1267)
評論(0) 編輯 收藏