4 回答

TA貢獻(xiàn)1943條經(jīng)驗(yàn) 獲得超7個(gè)贊
事件處理程序是非常明顯的內(nèi)存泄漏的常見來源。如果您從object2訂閱了object1上的事件,則執(zhí)行object2.Dispose()并假裝該事件不存在(并從代碼中刪除所有引用),則object1的事件中存在一個(gè)隱式引用,這將阻止object2被垃圾收集。
MyType object2 = new MyType();
// ...
object1.SomeEvent += object2.myEventHandler;
// ...
// Should call this
// object1.SomeEvent -= object2.myEventHandler;
object2.Dispose();
這是泄漏的常見情況-忘記輕松取消訂閱事件。當(dāng)然,如果收集了object1,則也將收集object2,但要到那時(shí)為止。

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊
我認(rèn)為C ++風(fēng)格的內(nèi)存泄漏是不可能的。垃圾收集器應(yīng)解決這些問題。即使不再使用這些對(duì)象,也可以創(chuàng)建一個(gè)聚合對(duì)象引用的靜態(tài)對(duì)象。像這樣:
public static class SomethingFactory
{
private static List<Something> listOfSomethings = new List<Something>();
public static Something CreateSomething()
{
var something = new Something();
listOfSomethings.Add(something);
return something;
}
}
那顯然是一個(gè)愚蠢的例子,但這等同于托管運(yùn)行時(shí)內(nèi)存泄漏。

TA貢獻(xiàn)1856條經(jīng)驗(yàn) 獲得超17個(gè)贊
正如其他人指出的那樣,只要在內(nèi)存管理器中沒有實(shí)際的錯(cuò)誤,不使用非托管資源的類就不會(huì)泄漏內(nèi)存。
在.NET中看到的不是內(nèi)存泄漏,而是永不處置的對(duì)象。只要垃圾收集器可以在對(duì)象圖上找到對(duì)象,該對(duì)象就不會(huì)被處置。因此,如果任何活動(dòng)對(duì)象在任何地方都具有對(duì)該對(duì)象的引用,則該對(duì)象不會(huì)被丟棄。
事件注冊(cè)是實(shí)現(xiàn)此目標(biāo)的好方法。如果一個(gè)對(duì)象注冊(cè)了一個(gè)事件,則無論它注冊(cè)了什么對(duì)象,都具有對(duì)該事件的引用,并且即使您消除了對(duì)該對(duì)象的所有其他引用,直到該對(duì)象取消注冊(cè)(或與其注冊(cè)的對(duì)象變得不可訪問),它仍將保持活動(dòng)狀態(tài)。
因此,您必須注意在不知情的情況下注冊(cè)靜態(tài)事件的對(duì)象。ToolStrip例如,的一個(gè)漂亮功能是,如果您更改顯示主題,它將自動(dòng)在新主題中顯示。它通過注冊(cè)靜態(tài)SystemEvents.UserPreferenceChanged事件來實(shí)現(xiàn)此精美功能。更改Windows主題時(shí),將引發(fā)該事件,并且ToolStrip正在監(jiān)聽該事件的所有對(duì)象都將收到一個(gè)新主題的通知。
好的,假設(shè)您決定放棄ToolStrip表格上的:
private void DiscardMyToolstrip()
{
Controls.Remove("MyToolStrip");
}
您現(xiàn)在擁有一個(gè)ToolStrip永不消逝的世界。即使它不再存在于您的表單中,每次用戶更改主題時(shí),Windows都會(huì)忠實(shí)地告知ToolStrip有關(guān)此主題的信息。每當(dāng)垃圾收集器運(yùn)行時(shí),它都會(huì)認(rèn)為“我不能扔掉該對(duì)象,UserPreferenceChanged事件正在使用它?!?/p>
那不是內(nèi)存泄漏。但也可能如此。
這樣的事情使內(nèi)存分析器變得無價(jià)。運(yùn)行一個(gè)內(nèi)存分析器,您會(huì)說:“很奇怪ToolStrip,即使我的表單上只有一個(gè)對(duì)象,堆上似乎有一萬個(gè)對(duì)象。這是怎么發(fā)生的?”
哦,如果您想知道為什么有些人認(rèn)為屬性設(shè)置者是邪惡的:ToolStrip要從UserPreferenceChanged事件中取消注冊(cè),請(qǐng)將其Visible屬性設(shè)置為false。
- 4 回答
- 0 關(guān)注
- 1117 瀏覽
添加回答
舉報(bào)