我有一个函数,它接受一个仿函数列表:
public void RunFunc(List<Func<double, double>> functorList)
问题在于Func<double, double>
分配了来自不同对象的方法。我现在关注的是垃圾收集器总是保存指向这些方法的指针,并且总是为这些对象保留内存,因为GC不知道如何处理它们。
我是对的吗? RunFunc
会导致内存泄漏吗?如果是,我应该做些什么来释放List<Func<double, double>> functorList
所拥有的记忆?
答案 0 :(得分:3)
不,这不会导致内存泄漏。
一旦List<>
无法访问,它就会被收集。 Func<>
项是outgoinf参考。只有传入的引用才能保持活着。
答案 1 :(得分:3)
您正在创建一个委托列表,当此列表存在时,它将保存对每个委托引用的每个对象的引用。
如果RunFunc
方法将此列表存储为成员,则只要存储列表,就不会对对象进行垃圾回收。这是一件好事 - 否则以后可能会尝试在已被销毁的对象上调用函数。
一旦列表停止被引用,它将不再阻止对象被垃圾回收。
因此,在回答您的问题时,RunFunc
与任何其他CLR方法没有任何不同,并且将一如既往地应用相同的垃圾收集规则。
这是一个更简单的例子:
Action myAction = null;
{
var widget = new Widget();
myAction = () => { widget.ScooblyWob() };
}
// the widget object has gone out of scope, but will stay in memory
// It is not a candidate for garbage collection, because
// it is being referenced by the myAction function.
myAction();
// Even though I have no explicit references to the widget,
// I just called a function on it!
myAction = null;
// Now the action has been dereferenced,
// so the widget is a garbage collection candidate