java語(yǔ)言中的垃圾回收機(jī)制_第1頁(yè)
java語(yǔ)言中的垃圾回收機(jī)制_第2頁(yè)
java語(yǔ)言中的垃圾回收機(jī)制_第3頁(yè)
java語(yǔ)言中的垃圾回收機(jī)制_第4頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

java語(yǔ)言中的垃圾回收機(jī)制

java是描述平臺(tái)應(yīng)用的面向的編程語(yǔ)言,由sun微軟系統(tǒng)的詹姆斯斯林和其他人于20世紀(jì)90年代初開發(fā)。伴隨著Java技術(shù)的普及,網(wǎng)絡(luò)上越來(lái)越多的服務(wù)器程序采用Java技術(shù),特別是Internet使Java成為網(wǎng)上最流行的編程語(yǔ)言。在傳統(tǒng)的高級(jí)編程語(yǔ)言(例C++)中,對(duì)象的創(chuàng)建和回收均由程序員自行負(fù)責(zé),如果創(chuàng)建了對(duì)象而忘記回收,則會(huì)造成內(nèi)存泄漏,長(zhǎng)此以往,程序運(yùn)行的時(shí)候可能會(huì)生成很多不清除的垃圾,浪費(fèi)了不必要的內(nèi)存空間,有時(shí)還可能引起系統(tǒng)的崩潰。在Java中,引入了垃圾回收機(jī)制:垃圾回收器(GarbageCollector,GC),可以自動(dòng)回收內(nèi)存中的垃圾,這是Java語(yǔ)言相對(duì)于其它語(yǔ)言的優(yōu)勢(shì),但是內(nèi)存泄漏并不會(huì)因此而完全避免。1自動(dòng)的垃圾回收機(jī)制大多數(shù)C++編譯器不支持垃圾回收機(jī)制。通常使用C++編程的時(shí)候,程序員所創(chuàng)建的對(duì)象在創(chuàng)建時(shí)在堆棧上分配一塊內(nèi)存地址,當(dāng)不需要這個(gè)對(duì)象,進(jìn)行析構(gòu)或者刪除的時(shí)候再釋放分配的內(nèi)存空間。如果對(duì)象是在堆上分配了,而程序員又忘記進(jìn)行釋放,這些空間又無(wú)法自動(dòng)回收,就會(huì)造成內(nèi)存泄漏。而無(wú)法回收的內(nèi)存空間,即丟失的內(nèi)存(稱為“垃圾”),除非是重新啟動(dòng)系統(tǒng)否則永遠(yuǎn)也不會(huì)還給操作系統(tǒng)。長(zhǎng)此以往,程序運(yùn)行的時(shí)候可能會(huì)生成很多垃圾,浪費(fèi)了不必要的內(nèi)存空間。更糟糕的是,如果同一內(nèi)存地址被刪除兩次的話,程序會(huì)變得不穩(wěn)定,甚至崩潰。Java語(yǔ)言則不同,上述的情況被自動(dòng)垃圾回收機(jī)制自動(dòng)處理。對(duì)象的建立和放置都是在內(nèi)存堆棧上面進(jìn)行的。程序或者其他的對(duì)象可以鎖定一塊堆棧地址來(lái)進(jìn)行其他對(duì)象的引用。當(dāng)一個(gè)對(duì)象沒(méi)有任何引用的時(shí)候,Java的自動(dòng)垃圾回收機(jī)制就發(fā)揮作用,自動(dòng)刪除這個(gè)對(duì)象所占用的空間,釋放內(nèi)存以避免內(nèi)存泄漏。但是內(nèi)存泄漏并不是就此而完全避免了,當(dāng)程序員疏忽大意地忘記解除一個(gè)對(duì)象不應(yīng)該有的引用的時(shí)候,內(nèi)存泄漏仍然不可避免,不過(guò)發(fā)生的幾率要比不啟用垃圾回收機(jī)制的C++程序少很多。但是總體來(lái)講,自動(dòng)垃圾回收機(jī)制要安全和簡(jiǎn)單許多。2垃圾回收機(jī)制2.1引用對(duì)象已經(jīng)超過(guò)其作用域垃圾,內(nèi)存中的垃圾,即內(nèi)存中已無(wú)效但又無(wú)法自動(dòng)釋放的空間。在Java語(yǔ)言中,沒(méi)有引用句柄指向的類對(duì)象最容易成為垃圾。產(chǎn)生垃圾的情況有很多,主要有以下3種:(1)超出對(duì)象的引用句柄的作用域時(shí),這個(gè)引用句柄引用的對(duì)象就變成垃圾。例1引用句柄p1的作用域是從定義到“}”處,執(zhí)行完這對(duì)大括號(hào)中的所有代碼后,產(chǎn)生的Person對(duì)象就會(huì)變成垃圾,因?yàn)橐眠@個(gè)對(duì)象的句柄p1已超過(guò)其作用域,p1已經(jīng)無(wú)效,Person對(duì)象不再被任何句柄引用了。(2)沒(méi)有超出對(duì)象的引用句柄的作用域時(shí),給這個(gè)引用句柄賦值為空時(shí),這個(gè)引用句柄引用的對(duì)象就變成垃圾。例2在執(zhí)行完“p1=null;”后,即使句柄p1還沒(méi)有超出其作用域,仍然有效,但它已被賦值為空,不再指向任何對(duì)象,則這個(gè)Person對(duì)象不再被任何句柄引用,變成了垃圾。此后p1還可以指向其它Person對(duì)象,因?yàn)檫€沒(méi)有超出它的作用域。(3)創(chuàng)建匿名對(duì)象時(shí),匿名對(duì)象用完以后即成垃圾。例3因此,在程序中應(yīng)盡量少用匿名對(duì)象。2.2釋放內(nèi)存空間在Java程序運(yùn)行過(guò)程中,一個(gè)垃圾回收器(GarbageCollector,簡(jiǎn)稱GC)會(huì)不定時(shí)地被喚起檢查是否有不再被使用的對(duì)象,并釋放它們占用的內(nèi)存空間。垃圾回收器的回收無(wú)規(guī)律可循,可能在程序的運(yùn)行的過(guò)程中,一次也沒(méi)有啟動(dòng),也可能啟動(dòng)很多次。因此,并不會(huì)因?yàn)槌绦虼a一產(chǎn)生垃圾,垃圾回收器就馬上被喚起而自動(dòng)回收垃圾,很可能到程序結(jié)束時(shí)垃圾回收器都沒(méi)有啟動(dòng)。所以垃圾回收器并不能完全避免內(nèi)存泄漏的問(wèn)題。另一方面,垃圾回收會(huì)給系統(tǒng)資源帶來(lái)額外的負(fù)擔(dān)和時(shí)空開銷。它被啟動(dòng)的幾率越小,帶來(lái)的負(fù)擔(dān)的幾率就越小。因此,垃圾的回收策略也很重要。2.3次釋放型內(nèi)存空間不同廠商、不同版本的Java虛擬機(jī)中的內(nèi)存垃圾回收機(jī)制并不完全一樣,通常越新版本的內(nèi)存回收機(jī)制越快。而不同的Java虛擬機(jī)采用不同的回收策略,常用的有兩種:復(fù)制式回收策略和自省式回收策略。復(fù)制式回收策略:先將正在運(yùn)行中的程序暫停,然后把正在被使用的所有對(duì)象從它們所在的堆內(nèi)存A里復(fù)制到另一塊堆內(nèi)存B,再釋放堆內(nèi)存A中的所有空間,這些不再使用的對(duì)象所占用的內(nèi)存空間就會(huì)被釋放掉。這種方式需要維護(hù)所需內(nèi)存數(shù)量的至少兩倍的內(nèi)存空間,適合垃圾比較多的情況。當(dāng)程序只產(chǎn)生了少量垃圾或者沒(méi)有垃圾時(shí),這種回收策略的效率就非常低。自省式回收策略:首先檢測(cè)所有正在使用的對(duì)象,并為它們標(biāo)注,比如用1來(lái)標(biāo)注正在使用的對(duì)象,用0來(lái)標(biāo)注不再被使用的對(duì)象,然后將所有標(biāo)注為0的內(nèi)存空間一次釋放。因?yàn)闃?biāo)注會(huì)增大系統(tǒng)的開銷,因此這種方式的速度仍然很慢,尤其是在垃圾比較多的情況下,效率會(huì)很低。這種方法適合垃圾比較少的情況。這兩種方式具有互補(bǔ)性,因此在一些Java虛擬機(jī)中兩種方式被有機(jī)的結(jié)合運(yùn)用。由于Java的垃圾回收器的啟用不由程序員控制,而且回收也無(wú)規(guī)律可循,并不會(huì)一產(chǎn)生了垃圾,垃圾回收器就被喚起;有時(shí)甚至可能到程序終止,回收器都沒(méi)有啟動(dòng)的機(jī)會(huì)。因此這個(gè)垃圾回收機(jī)制不是一個(gè)很可靠的機(jī)制。因?yàn)槔荒芗皶r(shí)回收,它們所占用的內(nèi)存空間不能釋放,就會(huì)影響程序的性能;如果某段程序產(chǎn)生大量的垃圾而沒(méi)有回收,回收工作也會(huì)變得困難。為了解決這個(gè)問(wèn)題,Java提供一個(gè)System.gc()方法,可以強(qiáng)制啟動(dòng)垃圾回收器來(lái)回收垃圾,以減少內(nèi)存泄露發(fā)生的概率。例4匿名對(duì)象會(huì)產(chǎn)生垃圾,如果擔(dān)心這些垃圾不能及時(shí)回收,可以在使用完這些匿名對(duì)象以后,加上一條語(yǔ)句:System.gc(),強(qiáng)制啟動(dòng)垃圾回收器來(lái)回收垃圾。程序的運(yùn)行結(jié)果如圖2所示。System.gc()有一個(gè)特點(diǎn),就是在對(duì)象被當(dāng)成垃圾從內(nèi)存中釋放前要調(diào)用finalize()方法,而且釋放一個(gè)對(duì)象調(diào)用一次finalize()方法。從程序的運(yùn)行結(jié)果可以看到:垃圾回收器啟動(dòng)以后,并不一定馬上回收垃圾,很可能要等待一段時(shí)間才執(zhí)行。這是因?yàn)樵诔绦蜻\(yùn)行過(guò)程中,垃圾收集線程優(yōu)先級(jí)比較低,如果有比這個(gè)線程優(yōu)先級(jí)高的線程,先運(yùn)行這些優(yōu)先級(jí)高的線程,等這些線程執(zhí)行完畢,才進(jìn)行垃圾回收。所以System.gc()方法只是一種“建議”,它建議Java虛擬機(jī)執(zhí)行垃圾回收,釋放內(nèi)存空間,但不能夠預(yù)知什么時(shí)候能夠回收。如果把“System.gc();”語(yǔ)句,放在第二個(gè)匿名對(duì)象語(yǔ)句后面,再進(jìn)行編譯和執(zhí)行,其結(jié)果將如圖3所示。這是因?yàn)?啟動(dòng)完垃圾回收器以后,它只能檢測(cè)到在垃圾回收器強(qiáng)制啟動(dòng)之前程序運(yùn)行所產(chǎn)生的垃圾,Java的虛擬機(jī)盡最大的努力從被丟棄的對(duì)象上回收垃圾;對(duì)于在啟動(dòng)垃圾回收器以后產(chǎn)生的垃圾,這個(gè)線程檢測(cè)到的概率就非常小了,如果檢測(cè)不到,就不能回收這些垃圾。因此,Java中的垃圾回收器機(jī)制及System.gc()方法,并不能夠完全避免內(nèi)存泄露的問(wèn)題,只是盡可能降低內(nèi)存泄露的可能性和程度。4java編程中應(yīng)該注意的問(wèn)題為了提高垃圾的回收效率,在實(shí)際應(yīng)用中,使用下列幾種方法可以在一定程度上避免Java中的內(nèi)存泄露。(1)盡量利用公開對(duì)象,忽視內(nèi)部模式匿名對(duì)象被使用完以后就會(huì)變成垃圾;而在內(nèi)部類中,隱含著一個(gè)外部類對(duì)象的引用,這個(gè)引用也無(wú)法自動(dòng)消除。(2)調(diào)用tableity方法因?yàn)镾ystem.gc()方法在回收每一個(gè)對(duì)象所占用的內(nèi)存空間時(shí),都會(huì)調(diào)用finalize()方法,在這個(gè)方法中的任何操作都會(huì)增加垃圾回收的開銷。(3)啟動(dòng)垃圾回收在程序中可以顯式地調(diào)用System.gc()方法,但這種方法不能保證清除所有的垃圾。另外垃圾回收也是一

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論