Pau*_*ich 15 c# closures garbage-collection
我是否需要将MyAction设置为null,以便垃圾收集能够继续使用这些类中的任何一个?
当两个班级的生命周期几乎相同时,我不太关心.当Class1的寿命比Class2长得多或者Class2的寿命比Class1长得多时,我的问题更合适.
这里的代码被删除了.假设Class1和Class2都包含可能影响其生命周期的其他成员和方法.
public class Class1 : IDisposable
{
public Action<string> MyAction { get; set; }
// Is this necessary?
public void Dispose()
{
MyAction = null;
}
}
public class Class2
{
string _result = string.Empty;
public void DoSomething()
{
Class1 myClass1 = new Class1();
myClass1.MyAction = s => _result = s;
myClass1.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 19
我是否需要将MyAction设置为null,以便垃圾收集能够继续使用这些类中的任何一个?
不会.任何时候你"管理"托管资源,你可能做错了.让垃圾收集器完成它的工作.
当两个班级的生命周期几乎相同时,我不太关心.当Class1的寿命比Class2长得多或者Class2的寿命比Class1长得多时,我的问题更合适.
这个问题没有任何意义; 班级没有生命.存储位置具有使用寿命.准确地说,您担心哪些存储位置?你能澄清一下这个问题吗?
我注意到,通过闭包延长封闭变量的寿命存在非常严重的问题; 然而,你的问题是如此模糊,以至于很难理解你是否遇到了这样的情况.让我来证明:
class Expensive
{
public byte[] huge = MakeHugeByteArray();
}
class Cheap
{
public int tiny;
}
class C
{
public static Func<Cheap> longLived;
public static void M()
{
Expensive expensiveLocal = new Expensive();
Cheap cheapLocal = new Cheap();
Func<Expensive> shortLived = ()=>expensiveLocal ;
C.longLived = ()=>cheapLocal;
}
}
Run Code Online (Sandbox Code Playgroud)
本地变量expensiveLocal的生命周期是多少?局部变量的生命周期通常很短 ; 通常局部变量不会超过方法激活.但是,处于闭包中会将局部变量的生命周期任意延长到闭包的生命周期.在这种特殊情况下,两个lambdas 共享一个闭包,这意味着局部变量expensiveLocal的生命周期至少与局部变量cheapLocal的生命周期一样长,因为对闭包的引用刚刚被存储,所以它具有无限长的生命周期.在一个永生的静态领域.这个大字节数组可能永远不会被回收,尽管很久以前就收集了似乎引用它的唯一东西; 闭包是一个隐藏的参考.
许多语言都有这个问题; C#,VB,JScript等都有词法闭包,这些闭包没有按生命周期分组到变量组.我们正在考虑改变C#和VB,以便对闭包进行更好的生命周期管理,但这是当前的远期工作,所以不能保证.