托管資源: Net平臺(tái)中,,CLR為程序員提供了一種很好的內(nèi)存管理機(jī)制,使得程序員在編寫(xiě)代碼時(shí)不要顯式的去釋放自己使用的內(nèi)存資源(這些在先前C和C++中是需要程序員自己去顯式的釋放的),。這種管理機(jī)制稱為GC(garbage collection),。GC的作用是很明顯的,當(dāng)系統(tǒng)內(nèi)存資源匱乏時(shí),,它就會(huì)被激發(fā),,然后自動(dòng)的去釋放那些沒(méi)有被使用的托管資源(也就是程序員沒(méi)有顯式釋放的對(duì)象)。 所以托管就是.net framework 負(fù)責(zé)幫你管理內(nèi)存及資源釋放,,不需要自己控制,,當(dāng)然對(duì)象只針對(duì)托管資源(部分引用類型), 不回收非托管資源。 像數(shù)組,,用戶定義的類,、接口、委托,,object,,字符串等引用類型,棧上保存著一個(gè)地址而已,,當(dāng)棧釋放后,, 即使對(duì)象已經(jīng)沒(méi)有用了,但堆上分配的內(nèi)存還在,,只能等GC收集時(shí)才能真正釋放 ,;但注意int,float,DateTime之類的值類型,GC會(huì)自動(dòng)釋放他們占用的內(nèi)存,,不需要GC來(lái)回收釋放 那么非托管的資源怎么釋放回收呢,?
對(duì)于非托管資源,GC只能跟蹤非托管資源的生存期,,而不知道如何去釋放它,。這樣就會(huì)出現(xiàn)當(dāng)資源用盡時(shí)就不能提供資源能夠提供的服務(wù),windows的運(yùn)行速度就會(huì)變慢,。比如當(dāng)你鏈接了數(shù)據(jù)庫(kù),,用完后你沒(méi)有顯式的釋放數(shù)據(jù)庫(kù)資源,如果還是不斷的申請(qǐng)數(shù)據(jù)庫(kù)資源,,那么到一定時(shí)候程序就會(huì)拋出一個(gè)異常,。
例如文件流,,數(shù)據(jù)庫(kù)的連接,系統(tǒng)的窗口句柄,,打印機(jī)資源等等,,當(dāng)你讀取文件之后,就需要對(duì)各種Stream進(jìn)行Dispose等操作,。比如 SqlDataReader 讀取數(shù)據(jù)完畢之后,,需要 reader.Dispose();等 Finalize一般情況下用于基類不帶close方法或者不帶Dispose顯式方法的類,,也就是說(shuō),在Finalize過(guò)程中我們需要隱式的去實(shí)現(xiàn)非托管資源的釋放,,然后系統(tǒng)會(huì)在Finalize過(guò)程完成后,,自己的去釋放托管資源。在.NET中應(yīng)該盡可能的少用析構(gòu)函數(shù)釋放資源,,MSDN2上有這樣一段話:實(shí)現(xiàn) Finalize 方法或析構(gòu)函數(shù)對(duì)性能可能會(huì)有負(fù)面影響,,因此應(yīng)避免不必要地使用它們。用 Finalize 方法回收對(duì)象使用的內(nèi)存需要至少兩次垃圾回收,。所以有析構(gòu)函數(shù)的對(duì)象,,需要兩次,第一次調(diào)用析構(gòu)函數(shù),,第二次刪除對(duì)象,。而且在析構(gòu)函數(shù)中包含大量的釋放資源代碼,會(huì)降低垃圾回收器的工作效率,,影響性能,。所以對(duì)于包含非托管資源的對(duì)象,最好及時(shí)的調(diào)用Dispose()方法來(lái)回收資源,,而不是依賴?yán)厥掌鳌?/p> Public class BaseResource:IDisposable { PrivateIntPtr handle; // 句柄,屬于非托管資源 PrivateComponet comp; // 組件,,托管資源 Privateboo isDisposed = false; // 是否已釋放資源的標(biāo)志 PublicBaseResource { } //實(shí)現(xiàn)接口方法 //由類的使用者,,在外部顯示調(diào)用,釋放類資源 Publicvoid Dispose() { Dispose(true);// 釋放托管和非托管資源 //將對(duì)象從垃圾回收器鏈表中移除,, // 從而在垃圾回收器工作時(shí),,只釋放托管資源,而不執(zhí)行此對(duì)象的析構(gòu)函數(shù) GC.SuppressFinalize(this); } //由垃圾回收器調(diào)用,,釋放非托管資源 ~BaseResource() { Dispose(false);// 釋放非托管資源 } //參數(shù)為true表示釋放所有資源,,只能由使用者調(diào)用 //參數(shù)為false表示釋放非托管資源,只能由垃圾回收器自動(dòng)調(diào)用 //如果子類有自己的非托管資源,,可以重載這個(gè)函數(shù),,添加自己的非托管資源的釋放 //但是要記住,重載此函數(shù)必須保證調(diào)用基類的版本,,以保證基類的資源正常釋放 Protectedvirtual void Dispose(bool disposing) { If(!this.disposed)// 如果資源未釋放 這個(gè)判斷主要用了防止對(duì)象被多次釋放 { If(disposing) { Comp.Dispose();// 釋放托管資源 } closeHandle(handle);// 釋放非托管資源 handle= IntPtr.Zero; } this.disposed= true; // 標(biāo)識(shí)此對(duì)象已釋放 } } 在C#中,,凡是繼承了IDisposable接口的類,,都可以使用using語(yǔ)句,,從而在超出作用域后,讓系統(tǒng)自動(dòng)調(diào)用Dispose()方法,。 |
|
來(lái)自: ontheroad96j47 > 《待分類》