2010-02-09 124 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对单个请求的现有引用进行清理,为每个新请求创建新控件。