|
垃圾收集器用來在.NET中進(jìn)行內(nèi)存管理,特別是它可以恢復(fù)正在進(jìn)行中的應(yīng)用程序需要的內(nèi)存。到目前為止,WINDOWS平臺(tái)已經(jīng)使用了兩種技術(shù)來釋放進(jìn)程向系統(tǒng)動(dòng)態(tài)請(qǐng)求的內(nèi)存:
讓應(yīng)用程序代碼負(fù)責(zé)釋放內(nèi)存是低級(jí)、高性能的語言使用的技術(shù),例如C++。這種技術(shù)很有效,而且可以讓資源在不需要的時(shí)候就釋放(一般情況下),但最大的缺點(diǎn)是頻繁出現(xiàn)錯(cuò)誤,請(qǐng)求內(nèi)存的代碼還必須明確通知系統(tǒng)它什么時(shí)候不再需要該內(nèi)存,但是這很容易被遺漏,從而導(dǎo)致內(nèi)存泄露。 盡管現(xiàn)代的開發(fā)環(huán)境提供了幫助檢測(cè)內(nèi)存泄露的工具,但它們很難追蹤錯(cuò)誤,因?yàn)橹钡絻?nèi)存已經(jīng)大量泄露從而已經(jīng)使WINDOWS拒絕為進(jìn)程提供資源時(shí),它們才會(huì)發(fā)揮作用。到那個(gè)時(shí)候,由于對(duì)內(nèi)存的需求,會(huì)使整個(gè)計(jì)算機(jī)變的相當(dāng)緩慢。 維護(hù)引用計(jì)數(shù)是COM對(duì)象采用的一種技術(shù),其方法是每個(gè)COM組件都保留一個(gè)計(jì)數(shù),記錄客戶機(jī)目前對(duì)它的引用數(shù)。當(dāng)這個(gè)計(jì)數(shù)下降到0的時(shí)候,組件就會(huì)自己刪除自己(侯杰曾經(jīng)在《程序員》雜志撰寫過自己刪除自己的組件的文章),并釋放相應(yīng)的內(nèi)存和資源,它帶來的問題是仍然需要客戶機(jī)通知組件它們已經(jīng)完成了內(nèi)存的使用。只要有一個(gè)客戶機(jī)沒有這么做,對(duì)象就仍然駐留在內(nèi)存中。在某些方面,這是比C++內(nèi)存泄露更加嚴(yán)重的問題,因?yàn)镃OM對(duì)象可能存在于它自己的進(jìn)程中,從來不會(huì)被系統(tǒng)刪除(在C++內(nèi)存泄露問題上系統(tǒng)至少可以在進(jìn)程中斷時(shí)候釋放所有的內(nèi)存)。 。NET運(yùn)行庫采用的方法是垃圾收集器,這是一個(gè)程序,其目的是清理內(nèi)存,方法是所有動(dòng)態(tài)請(qǐng)求的內(nèi)存都分配到堆上(這對(duì)所有的語言都一樣,但是在。NET中,CRL維護(hù)它自己的托管堆,以供。NET應(yīng)用程序使用)當(dāng)。NET檢測(cè)到給定進(jìn)程的托管堆已滿,需要清理時(shí),就調(diào)用垃圾收集器。垃圾收集器處理目前代碼中的所有變量檢查對(duì)存儲(chǔ)在托管上的對(duì)象的引用確定哪些對(duì)象可以從代碼中訪問——既哪些對(duì)象有引用。沒有引用的對(duì)象就不能再從代碼中訪問,因而被刪除。JAVA就使用與此類似的垃圾收集系統(tǒng)。 之所以在。NET中使用垃圾收集器,是因?yàn)橹虚g語言已用來處理進(jìn)程。其規(guī)則要求,第一,不能引用已有的對(duì)象,除非復(fù)制已有的引用。第二,中間語言是類型安全的語言。在這里,其含義是如果存在對(duì)對(duì)象的任何引用,該引用中就有足夠的信息來確定對(duì)象的類型。 垃圾收集器機(jī)制不能和諸如非托管C++的語言一起使用,因?yàn)镃++允許指針自由地轉(zhuǎn)換數(shù)據(jù)類型。 垃圾收集器的一個(gè)重要方面是它是不確定的。換而言之不能保證什么時(shí)候會(huì)調(diào)用垃圾收集器;。NET運(yùn)行庫決定需要它時(shí)就可以調(diào)用它(除非明確調(diào)用垃圾收集器)。但可以重寫這個(gè)過程,在代碼中調(diào)用垃圾收集器。 |
|
|