亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

【.NET深呼吸】清理對象引用,有一個問題容易被忽略

2019-11-14 16:10:33
字體:
來源:轉載
供稿:網友

大家知道,托管代碼一個重要的特點是自動管理內存,即我們常說的垃圾回收機制,那些高大上的理論我就不重復了,有興趣的朋友可以翻書。我這個有個毛病——不喜歡很嚴肅地去說一些理論的東西,所以我不多介紹了。

一般而言,當代碼執行超出某個變量的有效范圍后,或者不再引用某個對象實例時,該實例會發生析構,垃圾回收器很可能就要清理門戶了,當然也可能不是馬上清理,也許會過一會兒再清理。

對于一些要自定義進行清理操作的類,我們會采取以下方案:

1、寫上析構函數,在析構函數中清理。

2、實現IDisposable接口,并實現Dispose方法,在方法中編寫自定義清理代碼。當該類型被實例化后,最后不再使用時會調用Dispose方法清理,如果順利清理,最后還會調用類型的析構函數。通常,如何實現了IDisposable接口,就不必再寫上析構函數了。如果希望Dispose方法被自動調用,可以在實例化對象的代碼包裝在using語句塊中,當執行完using塊時會自動調用Dispose方法。

 

可能有人笑了,老周,你太逗了,這些基礎知識誰不知道?當然,我說上面那些內容是為了繞個小圈子,以便進入主題。于是,我產生了一個疑問:是不是存在某些情景下,可能導致對象實例不會被回收呢?就算你調用了Dispose方法,就算你把變量設為null來解除引用,就算你調用GC類的方法來回收……

經過老周測試,還真有這種情況,而且很多朋友都很有可能會忽略,甚至在意識認知上誤認為對象實例已經被回收,而實際上是沒有回收的。

 

我簡單說一下這種情形:

比如有一個靜態類(靜態類的成員必是靜態的)A,里面有靜態事件。隨后在其他類的實例中處理A類的靜態事件,并且處理事件的方法就位于這個實例對象上……

不急,我們還是看真實的例子吧。假如我定義了一個靜態類MyChecker,它里面有個靜態事件CheckEvent。

    public static class MyChecker    {        #region 靜態事件        public static event EventHandler CheckEvent;        #endregion        public static void CallEvent()        {            if (CheckEvent != null)            {                CheckEvent(new object(), EventArgs.Empty);            }        }    }

只要CallEvent方法被調用,CheckEvent事件會被引發。

 

然后,定義另一個類SampleClass,并在該類中處理剛才MyChecker中的靜態事件。

    class SampleClass:IDisposable    {        public SampleClass()        {            MyChecker.CheckEvent += MyChecker_CheckEvent;        }        void MyChecker_CheckEvent(object sender, EventArgs e)        {            new Form2().Show();        }        ~SampleClass()        {            System.Diagnostics.Debug.WriteLine("/n看,析構函數調用了。/n");        }        public void Dispose()        {            //……        }    }


在類的構造函數中,附加CheckEvent事件的處理,處理方法名為MyChecker_CheckEvent。

可能大家已經發現,老周寫的SampleClass類有點恐怖氣息,既實現了Dispose方法,怎么又寫了析構函數,我這里寫上析構函數是為了驗證類的實例是否真的被清理,如果實例真的被回收,那么Debug類會在“輸出”窗口中輸出提示,如果沒有提示輸出,說明類的實例還霸占著內存。

接下來測試一下。

            SampleClass sc = new SampleClass();            await Task.Delay(10 * 1000);            sc.Dispose();            sc = null;            GC.Collect();


實例化SampleClass后,然后Delay會暫停10秒,10秒鐘過后會調用Dispose方法,并設置變量為null引用,我害怕不能及時清理,連GC.Collect方法也用上了。

而在等待這10秒期間,可以調用靜態類的CallEvent方法來引發靜態事件CheckEvent。

MyChecker.CallEvent();

按照一般理解,在10秒鐘后,SampleClass實例應該被清理,并且在“輸出”窗口會輸出提示。

好,現在試一下。

……

實驗結果表明,輸出 窗口中連鴨毛都沒有輸出,這說明10秒鐘后,SampleClass實例根本沒有發生析構。于是又出問題了,這是怎么回事?SampleClass實例不是不存在引用了嗎,怎么不發生析構?

其實我們忽略了一點:靜態事件CheckEvent還跟SampleClass實例的方法綁定著呢,實質上,雖然將變量設為null,可是SampleClass實例中的MyChecker_CheckEvent方法還被靜態類中的靜態事件引用著,所以不會被回收。不知道你明白了沒。

這個問題很多朋友在實際開發中都會忽略,還得意地以為Sample實例真的被回收了,實際上實例不會被回收,除非程序結束。因為MyChecker是靜態類,不基于實例。如果MyChecker不是靜態類,那么當MyChecker的實例釋放后,SampleClass實例就可以被釋放了。

那么,如何解決呢?很簡單,只要在SampleClass類的Dispose方法中解除靜態事件與方法的綁定即可,這樣的話,靜態事件就不再引用實例中的方法成員了,此時實例就可以發生析構了。

        public void Dispose()        {            MyChecker.CheckEvent -= MyChecker_CheckEvent;        }

 

這個例子研究,告訴我們:在類實例中處理靜態事件時一定要小心

本示例的源碼下載:http://files.VEVb.com/files/tcjiaan/refsample.zip

好了,今天就扯到這里吧。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲码在线观看| 国产精品久久久久久久久| 欧美一级在线播放| 亚洲成人激情图| 国产精品网站视频| 午夜精品理论片| 国产日韩中文在线| 91亚洲精品在线| 日韩精品亚洲元码| 亚洲丁香婷深爱综合| 欧美激情中文字幕在线| 亚洲自拍偷拍一区| 欧美极度另类性三渗透| 亚洲一区二区三区久久| 国产精品网站大全| 日韩经典第一页| 中文字幕视频一区二区在线有码| 久久久久久久久久久免费精品| 黄色一区二区三区| 欧美激情网友自拍| 国产精品一区二区久久久| 日日狠狠久久偷偷四色综合免费| 久久精品精品电影网| 日韩中文在线中文网在线观看| 欧美日韩中文字幕日韩欧美| 日韩**中文字幕毛片| 亚洲的天堂在线中文字幕| 国产精品自产拍在线观看中文| 疯狂做受xxxx高潮欧美日本| 91免费看片网站| 97精品国产91久久久久久| 麻豆一区二区在线观看| 国产一区二区免费| 亚洲毛片在线观看.| 亚洲精品国偷自产在线99热| 最近中文字幕mv在线一区二区三区四区| 国产欧美日韩专区发布| 欧美尺度大的性做爰视频| 久久久久久成人| 在线日韩精品视频| 欧美刺激性大交免费视频| 伊人久久大香线蕉av一区二区| 国产婷婷成人久久av免费高清| 日韩国产欧美精品在线| 精品国偷自产在线视频| 日韩av电影中文字幕| 孩xxxx性bbbb欧美| 国产日韩欧美夫妻视频在线观看| 国产精品免费福利| 国产精品美女主播在线观看纯欲| 亚洲激情视频在线观看| 久久频这里精品99香蕉| 欧美精品一二区| 成人福利网站在线观看11| 91av在线视频观看| 久久久久久成人精品| 欧美巨乳在线观看| 国产网站欧美日韩免费精品在线观看| 久久91精品国产| 欧美天堂在线观看| 日韩中文字幕在线看| 在线成人中文字幕| 国产女人精品视频| 欧美性xxxx在线播放| 欧美成人免费一级人片100| 国产精品久久久久久久久久三级| 亚洲国产免费av| 91丝袜美腿美女视频网站| 国产成人精彩在线视频九色| 精品国产福利视频| 国产在线观看一区二区三区| 国产噜噜噜噜噜久久久久久久久| 亚洲精品资源美女情侣酒店| 欧美日韩激情视频| 最近日韩中文字幕中文| 国产精品久久久久久搜索| 亚洲香蕉成人av网站在线观看| 日韩在线视频中文字幕| 九九久久精品一区| 欧美高清电影在线看| 亚洲国产成人精品电影| 亚洲风情亚aⅴ在线发布| 96精品视频在线| 欧美中文在线免费| 日韩精品久久久久久久玫瑰园| 亚洲激情视频在线播放| 国产精品第一第二| 亚洲自拍偷拍色图| 中文字幕日本欧美| 国产在线精品一区免费香蕉| 亚洲精品白浆高清久久久久久| 亚洲欧美中文在线视频| 亚洲人成人99网站| 777精品视频| 国模叶桐国产精品一区| 亚洲欧美精品伊人久久| 日本国产一区二区三区| 亚洲国产97在线精品一区| 亚洲免费伊人电影在线观看av| 成人激情视频免费在线| 日韩精品极品视频| 亚洲精品视频播放| 欧美激情欧美狂野欧美精品| 国内精品久久久久久影视8| 久久久国产一区二区| xx视频.9999.com| 午夜精品久久久久久久99黑人| 97在线视频国产| 一本色道久久综合狠狠躁篇怎么玩| 大桥未久av一区二区三区| 国内精品中文字幕| 91精品国产99| 亚洲第一精品自拍| 日韩在线不卡视频| 欧美国产一区二区三区| 欧美高清自拍一区| 日韩va亚洲va欧洲va国产| 欧美三级免费观看| 欧美激情第99页| 2019中文字幕在线免费观看| 国产精品久久久久国产a级| 亚洲欧美日韩一区二区三区在线| 国产亚洲欧美日韩精品| 亚洲性夜色噜噜噜7777| 久久人人爽亚洲精品天堂| 日韩一区二区三区在线播放| 日韩精品一区二区视频| 久久在线免费视频| 国产亚洲激情视频在线| 欧美大片在线看| 日韩精品黄色网| 亚洲国产成人久久综合一区| 国产一区二区黄| 国产成人午夜视频网址| 久久久国产视频91| 伊人伊成久久人综合网小说| 精品久久中文字幕久久av| 亚洲高清久久久久久| 在线播放日韩精品| 日本久久精品视频| 日韩中文视频免费在线观看| 国产精品麻豆va在线播放| 欧美精品一区二区三区国产精品| 国产精品日韩av| 精品视频偷偷看在线观看| 91久久久久久久一区二区| 2018中文字幕一区二区三区| 精品久久中文字幕久久av| 精品久久香蕉国产线看观看亚洲| 国产精品日韩av| 另类专区欧美制服同性| 国产一区私人高清影院| 国产高清视频一区三区| 久久91亚洲精品中文字幕奶水| 日本中文字幕久久看| 日韩av在线看| 久久伊人91精品综合网站| 久久久久久久国产精品视频| 国产精品极品尤物在线观看| 中文字幕视频在线免费欧美日韩综合在线看| 国外日韩电影在线观看| 国模私拍视频一区| 一区二区三区视频免费在线观看| 九九热99久久久国产盗摄|