是什么让t
成为有根参考(留在范围内)? (t
是用户定义的类)
我在IL间谍中看到它,它不是一个常见的捕获变量!
Action runs = null;
while (dummy <= tod.Value.Date)
{
var t = new Task(dummy, _interval);
runs += t.Run;
dummy = dummy.AddDays(1);
}
GC.Collect();
((Action)(() => { runs(); })).BeginInvoke(Result, null);
有人可以向我解释一下吗? t
(任务)类如何保持在范围内,是什么使它成为根,我猜它的运行委托,但如何?
答案 0 :(得分:6)
首先,我应该指出,这与范围并不相关,范围是程序文本的一个区域,人们可以使用其简单名称来引用实体。它涉及可达性。
现在我还没有用内存分析器查看有问题的堆,但是Task
对象的路径看起来像这样:
Action
(多播)委托实例是GC根,因为它由runs
(本地)引用。 _invocationlist
字段保持其各个订阅者的活动,该字段包含对委托数组的引用。Action
委托实例的引用。 _target
字段(将作为this
引用传递给Task.Run
调用委托时的方法)。该字段将包含对Task
实例的引用。总结:
runs local
-> Multicast Action object
-> (through _invocationlist field) Array of references to Action objects
-> (through a specific array element) Unicast Action object
-> (through _target field) Task object
<强>更新强>
我通过Ants Memory Profiler运行了这个,这证实了我的想法: