第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將對象設置為null vs Dispose()

將對象設置為null vs Dispose()

守著星空守著你 2019-08-09 15:37:53
將對象設置為null vs Dispose()我對CLR和GC的工作方式很著迷(我正在通過C#,Jon Skeet的書籍/帖子等閱讀CLR來擴展我的知識)。無論如何,說:有什么區(qū)別:MyClass myclass = new MyClass();myclass = null;或者,通過使MyClass實現IDisposable和析構函數并調用Dispose()?此外,如果我有一個帶有using語句的代碼塊(例如下面的代碼),如果我單步執(zhí)行代碼并退出using塊,那么對象是在處理垃圾收集時發(fā)生的嗎?如果我在使用塊中調用Dispose()會發(fā)生什么?using (MyDisposableObj mydispobj = new MyDisposableObj()){}流類(例如BinaryWriter)有一個Finalize方法嗎?我為什么要用它?
查看完整描述

3 回答

?
茅侃侃

TA貢獻1842條經驗 獲得超22個贊

將處理與垃圾收集分開是很重要的。它們是完全不同的東西,有一個共同點我將在一分鐘內到達。

Dispose,垃圾收集和定稿

當你編寫一個using語句時,它只是try / finally塊的語法糖,因此Dispose即使using語句正文中的代碼拋出異常,也會調用它。這并不意味著該對象在塊的末尾被垃圾收集。

處置是關于非托管資源(非內存資源)。這些可能是UI句柄,網絡連接,文件句柄等。這些是有限的資源,因此您通常希望盡快釋放它們。IDisposable只要您的類型“擁有”非托管資源,您應該直接(通常通過一個IntPtr)或間接(例如通過a Stream,a SqlConnection等)實現。

垃圾收集本身只是關于內存 - 只有一點點扭曲。垃圾收集器能夠找到無法再引用的對象,并釋放它們。它不會一直尋找垃圾 - 只有當它檢測到它需要時(例如,如果堆的一個“代”耗盡內存)。

扭曲是最終確定。垃圾收集器保存一個不再可訪問的對象列表,但它們有一個終結器(用~Foo()C#編寫,有點令人困惑 - 它們與C ++析構函數完全不同)。它在這些對象上運行終結器,以防它們需要在釋放內存之前進行額外的清理。

在該類型的用戶忘記以有序方式處理它的情況下,終結器幾乎總是用于清理資源。因此,如果您打開FileStream但忘記調用DisposeClose,終結器最終將為您釋放基礎文件句柄。在一個寫得很好的程序中,終結者幾乎不應該在我看來。

將變量設置為 null

設置變量的一個小問題null- 為了垃圾收集,這幾乎不需要。如果它是一個成員變量,你有時可能想要這樣做,盡管根據我的經驗,不再需要一個對象的“部分”。當它是一個局部變量時,JIT通常足夠聰明(在發(fā)布模式下),以便知道何時不再使用引用。例如:

StringBuilder sb = new StringBuilder();

sb.Append("Foo");

string x = sb.ToString();


// The string and StringBuilder are already eligible

// for garbage collection here!

int y = 10;

DoSomething(y);


// These aren't helping at all!

x = null;

sb = null;


// Assume that x and sb aren't used here

一個時間它可能是值得設置一個局部變量null是當你在一個循環(huán),循環(huán)的一些分支機構需要使用變量,但你知道你已經達到在你做的不是一個點。例如:

SomeObject foo = new SomeObject();for (int i=0; i < 100000; i++){
    if (i == 5)
    {
        foo.DoSomething();
        // We're not going to need it again, but the JIT
        // wouldn't spot that
        foo = null;
    }
    else
    {
        // Some other code 
    }}

實現IDisposable / finalizers

那么,你自己的類型應該實現終結器嗎?幾乎肯定不是。如果你只間接持有非托管資源(例如你有FileStream一個成員變量),那么添加你自己的終結器將無濟于事:當你的對象出現時,流幾乎肯定有資格進行垃圾收集,所以你可以依賴FileStream有一個終結者(如果有必要 - 它可能會引用別的東西,等等)。如果你想“近乎”直接持有一個非托管資源,那么SafeHandle你的朋友 - 它需要一些時間才能開始,但這意味著你幾乎 不需要再次編寫終結器。如果你對資源有一個非常直接的處理(a IntPtr),你通常只需要一個終結器,你應該轉向SafeHandle你盡快做。(有兩個鏈接 - 理想情況下讀取兩個。)

Joe Duffy 有一套很長的關于終結者和IDisposable的指導方針(與很多聰明的人合寫)值得一讀。值得注意的是,如果你密封你的類,它會讓生活變得更容易:當你的類被設計為繼承時,覆蓋Dispose調用新的虛Dispose(bool)方法等的模式才有意義。

這有點絮絮叨叨,但請你澄清一下你想要的地方:)


查看完整回答
反對 回復 2019-08-09
?
明月笑刀無情

TA貢獻1828條經驗 獲得超4個贊

這兩項行動彼此沒有太大關系。當您將引用設置為null時,它只是這樣做。它本身并不會影響所引用的類。您的變量不再指向它以前使用的對象,但對象本身不變。

當你調用Dispose()時,它是對象本身的方法調用。無論Dispose方法做什么,現在都在對象上完成。但這不會影響您對該對象的引用。

唯一的重疊區(qū)域是,不再有對象的引用時,它最終會被垃圾收集。如果類實現了IDisposable接口,那么在對象被垃圾收集之前將調用Dispose()。

但是,在將引用設置為null之后,這不會立即發(fā)生,原因有兩個。首先,可能存在其他引用,因此它根本不會收集垃圾,其次,即使這是最后一個引用,所以現在它已經準備好被垃圾收集,在垃圾收集器決定刪除之前不會發(fā)生任何事情物體。

在對象上調用Dispose()不會以任何方式“殺死”對象。它通常用來清理,使該對象可以被安全地刪除之后,但最終,沒有什么神奇的有關Dispose,它只是一個類的方法。


查看完整回答
反對 回復 2019-08-09
  • 3 回答
  • 0 關注
  • 923 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號