中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

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

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

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

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

下面就來看看這兩個跟垃圾回收相關(guān)的方法。

Finalize方法

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

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

重寫Finalize方法

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

class MyResourceWrapper

{

protected override void Finalize()

{

}

}

名單

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

class MyResourceWrapper

{

~MyResourceWrapper()

{

Console.WriteLine("release unmanaged resources");

Console.Beep();

}

}

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

.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

當(dāng)我們執(zhí)行下面代碼時,我們就可以聽到系統(tǒng)蜂鳴聲,像我們前面介紹的一樣AppDomain被移除內(nèi)存,類型終結(jié)器將被調(diào)用。

static void Main(string[] args)

{

MyResourceWrapper mr = new MyResourceWrapper();

}

Finalize的工作機制

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

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

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

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

IDisposable接口

當(dāng)垃圾回收生效時,可以利用終結(jié)器來釋放非托管資源。然而,很多非托管資源都非常寶貴(如數(shù)據(jù)庫和文件句柄),所以它們應(yīng)該盡可能快的被清除,而不能依靠垃圾回收的發(fā)生。除了重寫Finalize之外,類還可以實現(xiàn)IDisposable接口,然后在代碼中主動調(diào)用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();

}

}

同樣,當(dāng)我們顯示的調(diào)用Dispose方法的時候,可以聽到系統(tǒng)的蜂鳴聲。

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

所以我們應(yīng)該使用下面的方式保證Dispose方法可以被調(diào)用到:

static void Main(string[] args)

{

MyResourceWrapper mr = new MyResourceWrapper();

try

{

//do something wiht mr object

}

finally

{

mr.Dispose();

}

}

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

重用using關(guān)鍵字

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

static void Main(string[] args)

{

using (MyResourceWrapper mr = new MyResourceWrapper())

{

//do something with mr object

}

}

在using語句塊結(jié)束的時候,mr實例的Dispose方法將會被自動調(diào)用。using語句不僅免除了程序員輸入Dispose調(diào)用的代碼,它還保證Dispose方法被調(diào)用,無論using語句塊順利執(zhí)行結(jié)束,還是拋出一個異常。事實上,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的結(jié)合

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

其實,MSDN上給我們提供了一種很好的模式來實現(xiàn)IDisposable接口來結(jié)合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)函數(shù)通過一個Disposing參數(shù)來區(qū)別當(dāng)前是否是被Dispose()調(diào)用。如果是被Dispose()調(diào)用,那么需要同時釋放托管和非托管的資源。如果是被終結(jié)器調(diào)用了,那么只需要釋放非托管的資源即可。Dispose()函數(shù)是被其它代碼顯式調(diào)用并要求釋放資源的,而Finalize是被GC調(diào)用的。

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

所以這個模式的優(yōu)點可以總結(jié)為:

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

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

總結(jié)

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

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

更多信息請查看IT技術(shù)專欄

更多信息請查看技術(shù)文章
易賢網(wǎng)手機網(wǎng)站地址:.NET垃圾回收:非托管資源
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2026上岸·考公考編培訓(xùn)報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報警專用圖標(biāo)
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
久久成人国产| 136国产福利精品导航网址| 亚洲一区二区在| 国产精品网红福利| 欧美日韩精品免费看| 久久久亚洲欧洲日产国码αv| 一区二区三区四区五区精品| 亚洲欧洲精品一区| 亚洲国产清纯| 在线看欧美视频| 黄色一区二区三区| 国产欧美精品xxxx另类| 国产精品试看| 欧美精品免费观看二区| 欧美精品播放| 欧美日韩免费观看一区三区 | 国产精品国产三级国产aⅴ入口| 欧美自拍偷拍| 久久久久天天天天| 免费欧美高清视频| 另类尿喷潮videofree| 另类亚洲自拍| 欧美区在线观看| 国产精品vvv| 国产伪娘ts一区| 国产视频不卡| 国产日韩欧美| 在线视频国产日韩| 亚洲欧洲综合| 欧美一区二区三区成人| 久久视频在线看| 欧美日韩一区二区三区免费| 国产精品综合色区在线观看| 国产综合av| 99国产精品久久久久久久成人热| 亚洲一区自拍| 欧美日韩成人一区| 亚洲风情亚aⅴ在线发布| 欧美一区二区黄色| 欧美午夜a级限制福利片| 激情综合视频| 久久xxxx精品视频| 国产日本欧美一区二区| 亚洲综合另类| 国产精品海角社区在线观看| 夜夜爽av福利精品导航| 欧美激情按摩| 最新中文字幕一区二区三区| 老司机免费视频一区二区| 国产综合网站| 久久综合网络一区二区| 91久久久久| 欧美日韩综合另类| 亚洲香蕉网站| 国产精品综合av一区二区国产馆| 亚洲网站啪啪| 国产亚洲欧美日韩日本| 久久国产成人| 亚洲国产精品悠悠久久琪琪| 欧美精选在线| 亚洲免费在线精品一区| 国产一二三精品| 欧美大片国产精品| 亚洲在线观看免费| 在线电影国产精品| 国产欧美日韩三区| 麻豆国产精品va在线观看不卡| 亚洲精品自在久久| 国产亚洲免费的视频看| 欧美日韩在线大尺度| 欧美成人嫩草网站| 亚洲国产精品久久久久秋霞不卡 | 亚洲字幕在线观看| 亚洲大片av| 猛男gaygay欧美视频| 亚洲少妇一区| 亚洲每日更新| 91久久精品国产91久久性色tv| 欧美视频一二三区| 欧美另类99xxxxx| 欧美**字幕| 欧美高清在线观看| 欧美肥婆bbw| 免费成人av| 欧美1级日本1级| 玖玖在线精品| 国产一区观看| 欧美四级在线观看| 欧美日韩一区二区欧美激情| 欧美黄色一区| 欧美久久99| 另类春色校园亚洲| 欧美sm视频| 欧美伦理视频网站| 欧美日韩国产免费观看| 开心色5月久久精品| 欧美不卡高清| 欧美视频在线视频| 国产亚洲成av人片在线观看桃| 国产精品夜色7777狼人| 国产欧美va欧美va香蕉在| 国产亚洲综合精品| 在线色欧美三级视频| 亚洲精品无人区| 一区二区三区国产精华| 一本一道久久综合狠狠老精东影业 | 久久精品国产亚洲aⅴ| 久久精品国产亚洲一区二区| 久久久久国产精品厨房| 欧美日产国产成人免费图片| 国产精品扒开腿做爽爽爽视频 | 99精品视频免费| 欧美中文字幕在线观看| 欧美成人午夜免费视在线看片| 亚洲国产精品一区| 亚洲精品社区| 欧美一区二区三区另类 | 香蕉久久夜色| 欧美日本网站| 亚洲国产高清视频| 亚洲人体影院| 久久久久久噜噜噜久久久精品| 欧美日韩精品久久| 在线日韩精品视频| 午夜老司机精品| 欧美日韩美女在线| 最新高清无码专区| 久久久久亚洲综合| 国产精品久久久久久一区二区三区| 玉米视频成人免费看| 欧美在线一区二区| 国产精品网站视频| 亚洲欧美国产一区二区三区| 欧美日韩亚洲一区在线观看| 亚洲国产99| 欧美成年人视频| 亚洲精品久久久久久一区二区| 猛男gaygay欧美视频| 羞羞漫画18久久大片| 性伦欧美刺激片在线观看| 欧美三级黄美女| 欧美日韩成人在线观看| 亚洲品质自拍| 欧美日韩1区2区| 中文亚洲视频在线| 国产精品xxx在线观看www| 亚洲永久精品大片| 国产性色一区二区| 久久影视精品| 亚洲精品午夜精品| 国产精品视频专区| 久久久久国产成人精品亚洲午夜| 亚洲大片av| 欧美日韩国产一区| 亚洲欧美日韩高清| 欧美日韩亚洲视频一区| 99v久久综合狠狠综合久久| 欧美日本一区二区高清播放视频| 国产精品成人aaaaa网站| 亚洲影院一区| 国产一区二区三区最好精华液| 亚洲第一精品福利| 欧美电影电视剧在线观看| 亚洲区一区二区三区| 欧美绝品在线观看成人午夜影视 | 亚洲第一级黄色片| 欧美伦理91| 亚洲欧美日韩在线观看a三区| 国产精品一区二区在线观看不卡| 一区二区三区久久| 国产亚洲综合性久久久影院| 美女视频黄 久久| 一区二区三区成人精品| 国产视频精品va久久久久久| 麻豆精品一区二区av白丝在线| 亚洲视频999| 亚洲黄色成人久久久| 国产日本欧美一区二区三区| 欧美另类69精品久久久久9999| 一个人看的www久久| 亚洲国产精品一区二区www| 国产精品另类一区| 欧美精品久久99| 久久看片网站| 欧美一区二区在线| 在线视频亚洲欧美| 亚洲精品美女在线观看播放| 国内自拍亚洲| 国产精品视频一区二区三区 | 一区二区三区四区蜜桃| 亚洲国产va精品久久久不卡综合| 欧美人与禽猛交乱配| 久久久精品国产一区二区三区| 欧美夜福利tv在线| 亚洲欧洲99久久| 欧美在线一级视频| 欧美一区二区三区四区在线观看| 中文一区字幕| 一区二区三区鲁丝不卡| 一区二区久久|