2010-02-09 123 views
4

委託會導致內存泄漏嗎?委託會導致內存泄漏嗎?

我的意思是,例如,如果一個類A包含ADelegate而後者指向BMethod(的B類)是否可以阻止GC的A類或B類集合?

如果是的話,我們怎麼能「免費」的代表(設置ADeletate = Nothing /空?)

你對此有何評論這一個:

//Class A Finalize, containing ADelegateInstance as ADelegate' 
protected override void Finalize() 
{ 
    ADelegateInstance = 
     (ADelegate)System.Delegate.RemoveAll(
      ADelegateInstance, ADelegateInstance); 
    ADelegateInstance = null; 
    base.Finalize(); 
} 

'Class A Finalize, containing ADelegateInstance as ADelegate' 
Protected Overrides Sub Finalize() 
    ADelegateInstance = _ 
     CType(System.Delegate.RemoveAll(ADelegateInstance, ADelegateInstance), _ 
      ADelegate) 
    ADelegateInstance = Nothing 
    MyBase.Finalize() 
End Sub 

回答

8

是,該引用,除非您取消訂閱的活路事件:

someObject.SomeEvent -= SomeDelegate; 
+0

如果我有一個具有多個委託訂閱/取消訂閱的大型複雜對象,最後在處理此對象時,我想讓這個委託的所有鏈接「讓我們死掉」。 – serhio 2010-02-09 08:53:39

+1

然後你可以實現IDisposable。 – 2010-02-09 09:02:14

+1

是的,我應該在該代理的Dispose方法中編寫什麼內容。 ,也許'System.Delegate.RemoveAll(myDelegate,myDelegate)'會有幫助嗎? – serhio 2010-02-09 09:04:30

2

據我所知,只要收集關閉/代表的是一個封閉/委託是指確實可以被垃圾背景下仍然被引用 - otherwis它會失去其背景。

answer爲例,我們看到委託人可以在對象上下文中引用變量inneri。所以實際上持有inneri的對象不能被垃圾收集,直到代理不再被引用,在這種情況下,直到Button被垃圾收集。

for (int i = 0; i < 7; i++) 
{ 
    var inneri = i; 
    Button newButton = new Button(); 
    newButton.Text = "Click me!"; 
    newButton.Click += delegate(Object sender, EventArgs e) 
    { 
     MessageBox.Show("I am button number " + inneri); 
    }; 
    this.Controls.Add(newButton); 
} 

相關文章:

+0

換句話說,你的意思是隻要ADelegate指出B就不會被收集? – serhio 2010-02-09 08:55:11

+0

是的,我認爲是這樣 – ewernli 2010-02-09 13:14:40

1

如果A包含了一個代表在B中的函數,那麼A將無法通過GC被銷燬。

每次編寫「mydelegate + = B.method」時,始終放入「mydelegate - = B.method」是個好主意。

儘管它不是真正的內存泄漏,因爲仍然可以訪問對象。

2

只是有一個引用不足以導致內存泄漏。考慮以下。

如果一個線程派生3個對象(其中 - >表示基準),A - >乙 - 「ç - >甲

如果A不是由線程引用,所有被收集。 GC提供循環參考。

但是,這也顯然意味着,如果一個委託包含對一個對象的引用,並且該委託對象仍然被引用,那麼委託函數將不會被清除。

這會給你下面的內容。

A - (帶代表的對象) B-包含函數引用的對象。

當A超出範圍,那麼B將會。

0

在ASP.NET應用程序中使用單例時出現了這種情況。由於某種原因,它曾經訂閱控制事件。事實上,它是一個單身人士(包含對自身的引用)不允許GC收集它,另一方面,單身人士從未刪除控制事件的訂閱。這導致了內存消耗的持續增長:控制用於處理單個請求,而不是由GC對單個請求的現有引用進行清理,爲每個新請求創建新控件。