亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍

.NET垃圾回收:非托管資源
來源:易賢網 閱讀:2162 次 日期:2015-04-02 13:11:22
溫馨提示:易賢網小編為您整理了“.NET垃圾回收:非托管資源”,方便廣大網友查閱!

前面一篇文章介紹了垃圾回收的基本工作原理,垃圾回收器并不是可以管理內存中的所有資源。對于所有的托管資源都將有.NET垃圾回收機制來釋放,但是,對于一些非托管資源,我們就需要自己編寫代碼來清理這類資源了。

其實在C#開發中,大部分資源都可以通過.NET垃圾回收機制進行回收,只用當我們使用非托管資源(原始的操作系統文件句柄,原始的非托管數據庫連接,非托管內存等等)的時候,我們才需要實現自己的資源清理代碼。

.NET提供了兩種釋放非托管資源的方式,類型自己的Finalize方法和IDisposable接口的Dispose方法。

下面就來看看這兩個跟垃圾回收相關的方法。

Finalize方法

在.NET的基類System.Object中,定義了名為Finalize()的虛方法,這個方法默認什么都不做。

我們可以為自定義的類型重寫Finalize方法,在該方法中加入必要的非托管資源清理邏輯。當要從內存中刪除這個類型的對象時,垃圾回收器會調用對象的Finalize方法。所以,無論.NET進行一次自發的垃圾回收,還是我們通過GC.Collect()進行強制垃圾回收,Finalize方法總是會被調用。另外,當承載應用程序的AppDomain從內存中移除時,同樣會調用Finalize方法。

重寫Finalize方法

假設我們現在有一個使用非托管資源的類型,那么我們就需要重寫Finalize方法來進行非托管資源的清理,但是當通過下面的方式重寫Finalize方法的時候,我們會得到一個編譯錯誤。

class MyResourceWrapper

{

protected override void Finalize()

{

}

}

名單

其實,當我們想要重寫Finalize方法時,C#為我們提供了(類似C++)析構函數語法(C#終結器)來重寫該方法。C#終結器和構造函數語法類似,方法名稱都和類型名稱一樣;不同的是,終結器具有~前綴,并且不能使用訪問修飾符,不接受參數,也不能重載,所以一個類只能有一個終結器。

class MyResourceWrapper

{

~MyResourceWrapper()

{

Console.WriteLine("release unmanaged resources");

Console.Beep();

}

}

之所以C#只支持這種方式進行Finalize方法的重寫,是因為C#編譯器會為Finalize方法隱式地加入一些必需的基礎代碼。下面就是我們通過ILSpy查看到了IL代碼,Finalize方法作用域內的代碼被放在了一個try塊中,然后不管在try塊中是否遇到異常,finally塊保證了Finalize方法總是能夠被執行。

.method family hidebysig virtual

instance void Finalize () cil managed

{

// Method begins at RVA 0x2050

// Code size 31 (0x1f)

.maxstack 1

.try

{

IL_0000: nop

IL_0001: ldstr "release unmanaged resources"

IL_0006: call void [mscorlib]System.Console::WriteLine(string)

IL_000b: nop

IL_000c: call void [mscorlib]System.Console::Beep()

IL_0011: nop

IL_0012: nop

IL_0013: leave.s IL_001d

} // end .try

finally

{

IL_0015: ldarg.0

IL_0016: call instance void [mscorlib]System.Object::Finalize()

IL_001b: nop

IL_001c: endfinally

} // end handler

IL_001d: nop

IL_001e: ret

} // end of method MyResourceWrapper::Finalize

當我們執行下面代碼時,我們就可以聽到系統蜂鳴聲,像我們前面介紹的一樣AppDomain被移除內存,類型終結器將被調用。

static void Main(string[] args)

{

MyResourceWrapper mr = new MyResourceWrapper();

}

Finalize的工作機制

Finalize的工作機制還是比較復雜的,這里只是簡單的介紹,更多的原理大家可以自己網上查查。

當在托管堆上分配對象空間時,運行庫會自動確定該對象是否提供一個自定義的Finalize方法。如果是這樣,對象被標記為可終結的,同時一個指向這個對象的指針被保存在名為終結隊列的內部隊列中。終結隊列是一個由垃圾回收器維護的表,它指向每一個在從堆上刪除之前必須終結的對象。

當垃圾回收器確定到了從內存中釋放一個對象的時間時,它檢查終結隊列上的每一個項,并將對象從堆上復制到另一個稱作終結可達表(finalization reachable table的托管結構上。此時,下一個垃圾回收時將產生另外一個線程,為每一個在可達表中的對象調用Finalize方法。因此,為了真正終結一個對象,至少要進行兩次垃圾回收。

從上面可以看到,Finalize方法的調用是相當消耗資源的。Finalize方法的作用是保證.NET對象能夠在垃圾回收時清理非托管資源,如果創建了一個不使用非托管資源的類型,實現終結器是沒有任何作用的。所以說,如果沒有特殊的需求應該避免重寫Finalize方法。

IDisposable接口

當垃圾回收生效時,可以利用終結器來釋放非托管資源。然而,很多非托管資源都非常寶貴(如數據庫和文件句柄),所以它們應該盡可能快的被清除,而不能依靠垃圾回收的發生。除了重寫Finalize之外,類還可以實現IDisposable接口,然后在代碼中主動調用Dispose方法來釋放資源。

看一個例子:

class MyResourceWrapper:IDisposable

{

public void Dispose()

{

Console.WriteLine("release resources with Dispose");

Console.Beep();

}

}

class Program

{

static void Main(string[] args)

{

MyResourceWrapper mr = new MyResourceWrapper();

mr.Dispose();

}

}

同樣,當我們顯示的調用Dispose方法的時候,可以聽到系統的蜂鳴聲。

注意,通過Dispose進行資源的釋放也是有潛在的風險的,因為Dispose方法需要被程序員顯示的調用,如果代碼中漏掉了Dispose的調用或者在Dispose調用之前產生了異常從而沒有指定Dispose,那么有些資源可能就一直留在內存中了。

所以我們應該使用下面的方式保證Dispose方法可以被調用到:

static void Main(string[] args)

{

MyResourceWrapper mr = new MyResourceWrapper();

try

{

//do something wiht mr object

}

finally

{

mr.Dispose();

}

}

但是,每次編寫Dispose的代碼都使用try塊會覺得很麻煩,還好C#中,我們可以重用using關鍵字來簡化Dispose的調用。

重用using關鍵字

在C#中,using語句提供了一個高效的調用對象Dispose方法的方式。對于任何IDispose接口的類型,都可以使用using語句,而對于那些沒有實現IDisposable接口的類型,使用using語句會導致一個編譯錯誤。

static void Main(string[] args)

{

using (MyResourceWrapper mr = new MyResourceWrapper())

{

//do something with mr object

}

}

在using語句塊結束的時候,mr實例的Dispose方法將會被自動調用。using語句不僅免除了程序員輸入Dispose調用的代碼,它還保證Dispose方法被調用,無論using語句塊順利執行結束,還是拋出一個異常。事實上,C#編譯器為using語句自動添加了try/finally塊。我們可以看看using的IL代碼:

.try

{

IL_0007: nop

IL_0008: nop

IL_0009: leave.s IL_001b

} // end .try

finally

{

IL_000b: ldloc.0

IL_000c: ldnull

IL_000d: ceq

IL_000f: stloc.1

IL_0010: ldloc.1

IL_0011: brtrue.s IL_001a

IL_0013: ldloc.0

IL_0014: callvirt instance void [mscorlib]System.IDisposable::Dispose()

IL_0019: nop

IL_001a: endfinally

} // end handler

Dispose和Finalize的結合

從前面的介紹了解到,Finalize可以通過垃圾回收進行自動的調用,而Dispose需要被代碼顯示的調用,所以,為了保險起見,對于一些非托管資源,還是有必要實現終結器的。也就是說,如果我們忘記了顯示的調用Dispose,那么垃圾回收也會調用Finalize,從而保證非托管資源的回收。

其實,MSDN上給我們提供了一種很好的模式來實現IDisposable接口來結合Dispose和Finalize,例如下面的代碼:

class MyResourceWrapper:IDisposable

{

private bool IsDisposed=false;

public void Dispose()

{

Dispose(true);

//tell GC not invoke Finalize method

GC.SuppressFinalize(this);

}

protected void Dispose(bool Disposing)

{

if(!IsDisposed)

{

if(Disposing)

{

//clear managed resources

}

//clear unmanaged resources

}

IsDisposed=true;

}

~MyResourceWrapper()

{

Dispose(false);

}

}

在這個模式中,void Dispose(bool Disposing)函數通過一個Disposing參數來區別當前是否是被Dispose()調用。如果是被Dispose()調用,那么需要同時釋放托管和非托管的資源。如果是被終結器調用了,那么只需要釋放非托管的資源即可。Dispose()函數是被其它代碼顯式調用并要求釋放資源的,而Finalize是被GC調用的。

另外,由于在Dispose()中已經釋放了托管和非托管的資源,因此在對象被GC回收時再次調用Finalize是沒有必要的,所以在Dispose()中調用GC.SuppressFinalize(this)避免重復調用Finalize。同樣,因為IsDisposed變量的存在,資源只會被釋放一次,多余的調用會被忽略。

所以這個模式的優點可以總結為:

如果沒有顯示的調用Dispose(),未釋放托管和非托管資源,那么在垃圾回收時,還會執行Finalize(),釋放非托管資源,同時GC會釋放托管資源

如果調用了Dispose(),就能及時釋放了托管和非托管資源,那么該對象被垃圾回收時,就不會執行Finalize(),提高了非托管資源的使用效率并提升了系統性能

總結

本文介紹了.NET垃圾回收中兩個相關的方法:Dispose和Finalize。Finalize的目的是用于釋放非托管的資源,而Dispose是用于釋放所有資源,包括托管的和非托管的。

Dispose需要在代碼中進行顯示的調用,而Finalize則是由垃圾回收自動調用,為了更有效的結合Dispose和Finalize,文中還介紹了MSDN中給出的實現IDisposable接口的一個模式。

更多信息請查看IT技術專欄

更多信息請查看技術文章
易賢網手機網站地址:.NET垃圾回收:非托管資源
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點

版權所有:易賢網

亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍
亚洲黄色精品| 欧美不卡高清| 欧美成人有码| 欧美日本三区| 在线欧美视频| 亚洲欧美日本视频在线观看| 久久国产精品免费一区| 欧美天天在线| 国产精品毛片| 欧美日韩精品不卡| 国产精品日韩欧美一区| 欧美精品一级| 中文精品视频一区二区在线观看| 欧美99在线视频观看| 激情另类综合| 欧美在线不卡| 国产精品免费一区二区三区在线观看 | 免费日韩一区二区| 国模 一区 二区 三区| 国产乱码精品| 亚洲狼人精品一区二区三区| 亚洲欧美一区在线| 久久电影一区| 国产伦精品一区二区三区高清版 | 久久国产日韩欧美| 99精品视频免费观看视频| 欧美日韩国产欧| 久久久成人网| 久久精品国产99精品国产亚洲性色| 91久久精品国产91久久性色tv| 欧美激情 亚洲a∨综合| 免费看亚洲片| 欧美在线综合| 久久久www| 久久精品中文字幕一区二区三区| 国产精品免费一区二区三区观看 | 亚洲福利免费| 国产精品hd| 欧美深夜福利| 国产精品多人| 亚洲图片欧洲图片日韩av| 国产一区高清视频| 国精品一区二区| 黑人一区二区三区四区五区| 欧美日韩1区| 国产一区再线| 亚洲久久视频| 亚洲欧美日韩一区在线观看| 亚洲一区二区三区涩| 久久av二区| 欧美一区亚洲| 在线成人国产| 亚洲免费一区二区| 欧美在线精品一区| 亚洲福利免费| 亚洲专区一区| 欧美三区在线| 国产欧美日本在线| 久久一区亚洲| 精品福利电影| 亚洲免费综合| 黑人一区二区| 国产精品一区二区三区观看| 欧美成人嫩草网站| 在线观看一区视频| 蜜桃久久av| 亚洲成人原创| 久久久综合网| 99成人免费视频| 久久久精品午夜少妇| 亚洲无毛电影| 久久亚洲国产精品一区二区| 好看的日韩av电影| 免费视频一区二区三区在线观看| 欧美精品二区| 国产日韩欧美一区二区| 久久综合久久综合这里只有精品| 激情视频一区| 欧美一区国产在线| 一区二区高清| 黄色一区三区| 欧美在线1区| 中文国产一区| 伊人天天综合| 欧美色图麻豆| 久久婷婷影院| 亚洲影院在线| 国产一级久久| 亚洲精品美女91| 国内精品亚洲| 欧美色图首页| 欧美福利精品| 久久久久久久久一区二区| 中文一区二区| 99精品热视频只有精品10| 国产精品国产亚洲精品看不卡15| 模特精品在线| 亚洲一区二区精品在线观看| 99精品热视频只有精品10| 亚洲天堂男人| 国产在线日韩| 红桃视频国产一区| 国产一区二区无遮挡| 欧美激情精品久久久六区热门| 欧美一级网站| 国产精品美女xx| 99一区二区| 99精品视频免费观看视频| 黄色亚洲在线| 影院欧美亚洲| 在线日韩电影| 日韩午夜免费视频| 99精品国产在热久久婷婷| 亚洲成人在线| 99在线精品免费视频九九视| 中国成人在线视频| 亚洲一区精彩视频| 久久都是精品| 欧美高清一区二区| 国产精品v欧美精品v日韩 | 国产一区视频观看| 国产精品多人| 一区在线视频观看| 日韩午夜精品| 嫩草成人www欧美| 午夜精品久久久久99热蜜桃导演 | 国产一区二区精品| 国产精品一区二区三区四区五区| 99精品视频免费观看视频| 亚洲美洲欧洲综合国产一区| 亚洲精品一区二| 国产欧美日韩一区| 久久精品一区二区国产| 欧美一区网站| 亚洲国产综合在线看不卡| 亚洲国产91| 国产乱码精品| 欧美日韩国产综合网| 亚洲福利av| 亚洲欧美日韩在线综合| 欧美三级特黄| 国产精品日韩欧美一区二区三区| 亚洲一区尤物| 国产一区二区中文| 亚洲一区二区三区高清不卡| 欧美91福利在线观看| 亚洲国产专区校园欧美| 老司机一区二区三区| 国产精品videossex久久发布| 亚洲国产三级| 午夜国产欧美理论在线播放| 亚洲色诱最新| 国产精品hd| 久久精品人人| 一本久久综合| 伊人影院久久| 欧美日韩调教| 久久av一区二区三区亚洲| 亚洲激情偷拍| 国内一区二区三区在线视频| 久久欧美肥婆一二区| aa级大片欧美三级| 伊人久久亚洲影院| 狂野欧美性猛交xxxx巴西| 夜夜精品视频| 在线日韩中文| 亚洲一二三区在线| 欧美 日韩 国产一区二区在线视频 | 亚洲高清视频一区二区| 葵司免费一区二区三区四区五区| 一区二区国产精品| 在线国产欧美| 国产伊人精品| 欧美fxxxxxx另类| 久久riav二区三区| 亚洲欧美日韩精品一区二区| 在线亚洲自拍| 宅男噜噜噜66国产日韩在线观看| 精品福利av| 在线观看一区| 亚洲人体偷拍| 亚洲精品精选| 亚洲精品一二| 中日韩男男gay无套| 一本色道婷婷久久欧美| 亚洲第一在线综合在线| 韩日成人av| 亚洲国产高清一区二区三区| 狠狠入ady亚洲精品经典电影| 狠狠色狠狠色综合日日tαg| 韩国亚洲精品| 亚洲精美视频| 一区二区精品在线| 国产伦精品一区| 亚洲一区观看| 久久精品二区| 欧美激情日韩| 亚洲国产精品123| 一二三区精品| 免费看的黄色欧美网站| 久久久亚洲人| 红桃视频国产精品| 亚洲激情一区二区三区| 国产日韩久久| 久久久久在线| 狠狠88综合久久久久综合网| 亚洲精品日韩在线观看| 香蕉视频成人在线观看| 欧美一区二区视频在线| 国产一区二区中文| 9国产精品视频| 久久成人亚洲| 黄色日韩精品| 男人的天堂亚洲在线| 午夜久久影院| 一级成人国产| 欧美搞黄网站| 国产午夜精品在线| 午夜国产一区| 在线亚洲免费| 欧美先锋影音| 久久aⅴ国产紧身牛仔裤| 欧美三区不卡| 国产精品一区二区三区四区五区| 欧美 日韩 国产精品免费观看| 精品动漫3d一区二区三区免费版 | 亚洲黄色免费| 一本久久综合| 欧美日韩91| 国产精品推荐精品| 欧美午夜不卡影院在线观看完整版免费| 国产一区二区三区自拍| 亚洲自啪免费| 亚洲国产免费看| 亚洲欧美综合国产精品一区| 一区二区冒白浆视频| 欧美日韩一区二| 久久久久天天天天| 国产精品普通话对白| 亚洲一二区在线| 欧美精品一区二区视频 | 亚洲人成毛片在线播放女女| 你懂的成人av| 久久国产精品99国产| 一本色道久久综合一区| 国产尤物精品| 欧美精品二区三区四区免费看视频| 国产欧美日韩一区二区三区在线| 国产精品99免费看| 欧美成人一区二区在线| 久久国产主播精品| 久久不射2019中文字幕| 一区二区三区视频在线播放| 一区二区视频欧美| 好吊视频一区二区三区四区| 欧美日韩在线一二三| 欧美激情无毛| 欧美欧美全黄| 狠狠综合久久av一区二区老牛| 欧美日韩国产亚洲一区| 欧美日韩高清在线一区| 欧美区国产区| 午夜精品剧场| 狠狠色伊人亚洲综合网站色| 国产中文一区二区| 亚洲婷婷在线| 亚洲国产1区| 99精品国产在热久久下载| 影音先锋中文字幕一区二区| 伊人影院久久| 一道本一区二区| 亚洲一区二区四区| 香蕉久久夜色精品国产| 久久精品欧美| 欧美三级网页| 亚洲开发第一视频在线播放| 国产精品亚洲一区| 久久久久国产精品午夜一区| 午夜精品视频| 亚洲国产免费看| 欧美亚洲网站| 红桃视频欧美| 国产亚洲永久域名| 欧美阿v一级看视频| 韩日视频一区| 国产精品一区毛片| 欧美黄色aaaa| 亚洲经典自拍| 久久久久久亚洲精品杨幂换脸| 欧美日韩一区在线观看视频| 日韩一区二区久久| 久久综合狠狠综合久久综青草| 欧美特黄一级| 中文在线不卡| 欧美久久99| 国产精品久久久亚洲一区| 你懂的成人av| 国产欧美不卡| 欧美午夜视频在线| 亚洲专区免费| 亚洲欧洲一区| 午夜国产一区| 亚洲制服av| 99精品国产在热久久| 你懂的一区二区| 99国产精品私拍| 欧美三级特黄| 久久久久久九九九九| 日韩视频在线播放| 国产综合网站| 欧美国产91| 蜜桃av噜噜一区二区三区| 在线成人h网| 国产精品草草| 欧美一区国产一区| 亚洲一区二区三区免费观看| 亚洲国产二区| 国产一区二区中文| 欧美一区二区三区久久精品| 国产亚洲网站| 99视频一区| 亚洲国产精品第一区二区| 欧美精品三区| 久久中文欧美| 久久久久久穴| 噜噜噜91成人网| 亚洲影音先锋| 国产亚洲在线| 国产精品亚洲一区| 国产精品一区二区三区四区五区| 亚洲日本黄色| 最新国产乱人伦偷精品免费网站| 韩日成人在线| 狠狠色狠狠色综合人人| 国产精品大片| 国内精品久久久久久久97牛牛 | 在线视频亚洲| 99视频精品| 一区二区三区四区五区精品| 日韩一级免费| 99这里有精品| 国产精品午夜av在线| 亚洲一区二区在| 国产乱码精品一区二区三区不卡| 宅男噜噜噜66国产日韩在线观看| 亚洲国产成人不卡| 99xxxx成人网| 久久99伊人| 欧美喷水视频| 亚洲激情网站| 国产精品手机在线| 久久久久久久波多野高潮日日| 久久久福利视频| 国产精品高清一区二区三区| 国内外成人免费视频| 亚洲激情偷拍| 久久av一区二区| 欧美日韩一区自拍| 亚洲国产精品www| 亚洲一级在线| 欧美日韩岛国| 一区二区冒白浆视频| 噜噜噜躁狠狠躁狠狠精品视频| 欧美99在线视频观看| 国模 一区 二区 三区| 99在线精品免费视频九九视| 免费久久99精品国产自| 欧美午夜久久| 国产精品久久久一区二区| 欧美激情1区2区3区| 亚洲国产精品一区制服丝袜 | 亚洲第一黄网| 香蕉成人久久| 国产精品成人一区二区网站软件| 亚洲精品一级| 欧美在线国产| 国产日韩一区| 欧美婷婷久久| 性久久久久久| 亚洲国产日本| 欧美1区2区| 国产精品免费一区二区三区观看| 欧美一区激情| 99综合视频| 好吊色欧美一区二区三区视频| 国产欧美一区二区色老头 | 国产美女一区| 黄色国产精品| 欧美一区高清| 国产精品久久久一区二区| 国内在线观看一区二区三区| 男人的天堂成人在线| 亚洲日本黄色| 极品少妇一区二区三区| 老司机精品福利视频| 国产色综合网| 日韩视频一区| 亚洲精品三级| 亚洲国产精品一区| 国语自产精品视频在线看8查询8|