久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C# 托管資源與非托管資源

 ontheroad96j47 2021-11-08

托管資源:

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è)異常,。


所以,當(dāng)我們?cè)陬愔蟹庋b了對(duì)非托管資源的操作時(shí),,我們就需要顯式,,或者是隱式的釋放這些資源在.Net中釋放非托管資源主要有2種方式,,Dispose,,F(xiàn)inalize,而Finalize和Dispose方法分別就是隱式和顯式操作中分別使用到的方法,。

例如文件流,,數(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>

  托管資源指的是.NET可以自動(dòng)進(jìn)行回收的資源,,主要是指托管堆上分配的內(nèi)存資源。托管資源的回收工作是不需要人工干預(yù)的,,有.NET運(yùn)行庫(kù)在合適調(diào)用垃圾回收器進(jìn)行回收,。

         非托管資源指的是.NET不知道如何回收的資源,最常見(jiàn)的一類非托管資源是包裝操作系統(tǒng)資源的對(duì)象,,例如文件,,窗口,網(wǎng)絡(luò)連接,,數(shù)據(jù)庫(kù)連接,,畫(huà)刷,圖標(biāo)等,。這類資源,,垃圾回收器在清理的時(shí)候會(huì)調(diào)用Object.Finalize()方法。默認(rèn)情況下,,方法是空的,,對(duì)于非托管對(duì)象,需要在此方法中編寫(xiě)回收非托管資源的代碼,,以便垃圾回收器正確回收資源,。

         在.NET中,Object.Finalize()方法是無(wú)法重載的,編譯器是根據(jù)類的析構(gòu)函數(shù)來(lái)自動(dòng)生成Object.Finalize()方法的,,所以對(duì)于包含非托管資源的類,,可以將釋放非托管資源的代碼放在析構(gòu)函數(shù)。

         注意,,不能在析構(gòu)函數(shù)中釋放托管資源,,因?yàn)槲鰳?gòu)函數(shù)是有垃圾回收器調(diào)用的,,可能在析構(gòu)函數(shù)調(diào)用之前,,類包含的托管資源已經(jīng)被回收了,從而導(dǎo)致無(wú)法預(yù)知的結(jié)果,。

         本來(lái)如果按照上面做法,,非托管資源也能夠由垃圾回收器進(jìn)行回收,但是非托管資源一般是有限的,,比較寶貴的,,而垃圾回收器是由CRL自動(dòng)調(diào)用的,這樣就無(wú)法保證及時(shí)的釋放掉非托管資源,,因此定義了一個(gè)Dispose()方法,,讓使用者能夠手動(dòng)的釋放非托管資源。Dispose()方法釋放類的托管資源和非托管資源,,使用者手動(dòng)調(diào)用此方法后,,垃圾回收器不會(huì)對(duì)此類實(shí)例再次進(jìn)行回收。Dispose()方法是由使用者調(diào)用的,,在調(diào)用時(shí),,類的托管資源和非托管資源肯定都未被回收,所以可以同時(shí)回收兩種資源,。

         Microsoft為非托管資源的回收專門定義了一個(gè)接口:IDisposable,,接口中只包含一個(gè)Dispose()方法。任何包含非托管資源的類,,都應(yīng)該繼承此接口,。

         在一個(gè)包含非托管資源的類中,關(guān)于資源釋放的標(biāo)準(zhǔn)做法是:

         (1)     繼承IDisposable接口,;

         (2)     實(shí)現(xiàn)Dispose()方法,,在其中釋放托管資源和非托管資源,并將對(duì)象本身從垃圾回收器中移除(垃圾回收器不在回收此資源),;

         (3)     實(shí)現(xiàn)類析構(gòu)函數(shù),,在其中釋放非托管資源。

         在使用時(shí),,顯示調(diào)用Dispose()方法,,可以及時(shí)的釋放資源,同時(shí)通過(guò)移除Finalize()方法的執(zhí)行,提高了性能,;如果沒(méi)有顯示調(diào)用Dispose()方法,,垃圾回收器也可以通過(guò)析構(gòu)函數(shù)來(lái)釋放非托管資源,垃圾回收器本身就具有回收托管資源的功能,,從而保證資源的正常釋放,,只不過(guò)由垃圾回收器回收會(huì)導(dǎo)致非托管資源的未及時(shí)釋放的浪費(fèi)。

         在.NET中應(yīng)該盡可能的少用析構(gòu)函數(shù)釋放資源,。在沒(méi)有析構(gòu)函數(shù)的對(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)厥掌鳌?/span>

         上面就是.NET中對(duì)包含非托管資源的類的資源釋放機(jī)制,只要按照上面要求的步驟編寫(xiě)代碼,,類就屬于資源安全的類,。

         下面用一個(gè)例子來(lái)總結(jié)一下.NET非托管資源回收機(jī)制:

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ì)象已釋放 } }

         

         析構(gòu)函數(shù)只能由垃圾回收器調(diào)用,。

         Despose()方法只能由類的使用者調(diào)用。

         在C#中,,凡是繼承了IDisposable接口的類,,都可以使用using語(yǔ)句,,從而在超出作用域后,讓系統(tǒng)自動(dòng)調(diào)用Dispose()方法,。
         一個(gè)資源安全的類,,都實(shí)現(xiàn)了IDisposable接口和析構(gòu)函數(shù)。提供手動(dòng)釋放資源和系統(tǒng)自動(dòng)釋放資源的雙保險(xiǎn),。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多