.net 代理会导致内存泄漏吗?
代理会导致内存泄漏吗 我的意思是,例如,如果一个类.net 代理会导致内存泄漏吗?,.net,memory-leaks,delegates,.net,Memory Leaks,Delegates,代理会导致内存泄漏吗 我的意思是,例如,如果一个类a包含一个ADelegate,后者指向B(属于B类)的B方法,这能阻止GC收集a类或B类吗 如果是这样,我们如何“释放”代理(设置ADeletate=Nothing/null?) 您对此有何评论: //Class A Finalize, containing ADelegateInstance as ADelegate' protected override void Finalize() { ADelegateInstance =
a
包含一个ADelegate
,后者指向B
(属于B
类)的B方法,这能阻止GC收集a类或B类吗
如果是这样,我们如何“释放”代理(设置ADeletate=Nothing
/null?)
您对此有何评论:
//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
是的,除非您取消订阅活动,否则该引用将保持活动状态:
someObject.SomeEvent -= SomeDelegate;
好吧,只要闭包/委托仍然被引用,闭包/委托引用的上下文就不能被垃圾收集,否则它将丢失其上下文
举个例子,我们看到委托可以在对象的上下文中引用变量inneri
。因此,在委托不再被引用之前(在本例中,直到按钮
被垃圾收集之前),实际上包含inneri
的对象不能被垃圾收集
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);
}
for(int i=0;i<7;i++)
{
var inneri=i;
按钮newButton=新按钮();
Text=“单击我!”;
newButton.Click+=委托(对象发送方,事件参数e)
{
MessageBox.Show(“我是按钮编号”+inneri);
};
this.Controls.Add(newButton);
}
相关职位:
如果A包含对B中某个函数的委托,则GC不会销毁A
每次编写“mydelegate+=B.method”时,总是输入“mydelegate-=B.method”是个好主意
虽然这不是真正的内存泄漏,因为仍然可以访问对象。仅仅有一个引用不足以导致内存泄漏。请考虑以下内容:
如果一个线程生成了3个对象(其中->表示引用),则a->B->C->a
如果线程未引用,则收集所有。循环引用由GC处理
但是,这显然也意味着,如果委托包含对对象的引用,并且仍然引用了带有委托的对象,那么委托函数将不会被清除
这将为您提供以下信息
A-(带委托的对象)
B-包含函数引用的对象
当A不在范围内时,B将返回。在ASP.NET应用程序中使用单例时会出现这种情况。出于某种原因,它过去常常订阅控件的事件。它是单例(包含对自身的引用)这一事实不允许GC收集它,另一方面,单例从未删除对控制事件的订阅。这导致了内存消耗的永久性增长:用于为单个请求提供服务的控件,由于来自单例的现有引用而未被GC清理,为每个新请求创建的新控件。如果我有一个包含多个委托订阅/取消订阅的大型复杂对象,最后,在Dispose of this object中,我希望“让die”指向此委托的所有链接。然后您可以实现IDisposable.yes,以及我应该在Dispose方法中为该委托编写什么内容,也许System.Delegate.RemoveAll(myDelegate,myDelegate)
会有帮助吗?你会像我在示例中所说的那样去做。@serhio:语法不是问题的焦点。概念是一样的。换句话说,你的意思是只要ADelegate指向B,B就不会被收集?。。