操作<string> 未被垃圾收集。为什么?
Action<string> not garbage collected. Why?
似乎无法通过 GC 收集 Action。为什么?
WeakReference reference = null;
WeakReference reference2 = null;
new Action(() =>
{
Action<string> deliveryMessage = (ans) => { };
object a = new object();
reference = new WeakReference(deliveryMessage);
reference2 = new WeakReference(a);
}) ();
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.Null(reference2.Target); //True
Assert.Null(reference.Target); //False
我打算在 WeakReference 列表中使用 Action,但我需要先通过这个简单的测试...
lambda 表达式不使用任何捕获的变量,因此它被转换为静态方法。作为优化,为了防止分配引起的额外 GC 开销,还创建了一个静态委托字段。执行分配时会访问此静态字段。不是每次都创建一个新的委托。这个静态委托一旦被初始化,就永远不会被收集。您可以通过查看 decompilation.
来了解这一点
似乎无法通过 GC 收集 Action。为什么?
WeakReference reference = null;
WeakReference reference2 = null;
new Action(() =>
{
Action<string> deliveryMessage = (ans) => { };
object a = new object();
reference = new WeakReference(deliveryMessage);
reference2 = new WeakReference(a);
}) ();
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.Null(reference2.Target); //True
Assert.Null(reference.Target); //False
我打算在 WeakReference 列表中使用 Action,但我需要先通过这个简单的测试...
lambda 表达式不使用任何捕获的变量,因此它被转换为静态方法。作为优化,为了防止分配引起的额外 GC 开销,还创建了一个静态委托字段。执行分配时会访问此静态字段。不是每次都创建一个新的委托。这个静态委托一旦被初始化,就永远不会被收集。您可以通过查看 decompilation.
来了解这一点