【问题标题】:Does passing delegates to static classes cause leaks?将委托传递给静态类会导致泄漏吗?
【发布时间】:2012-08-15 06:39:27
【问题描述】:

在 .Net 2.0 中工作,即将将代码库迁移到 4.0

最近我一直在使用事件序列化类,并且发现我的事件订阅者(即表单)也会尝试序列化(我现在使用 [field:NonSerializable] 来阻止这种情况)。

这让我想到,如果我将委托传递给静态类的方法(仅用于方法范围),静态类是否根植于委托的所有者,导致其无法被 GC 收集?

我有一个静态 ListUtilities 类来处理 lambda 表达式以及静态缓存,我经常传递委托,想知道这是否会导致内存泄漏?

【问题讨论】:

  • 鉴于 LINQ 是建立在扩展方法之上的,扩展方法是静态方法的语法糖,你认为这对于任何使用 LINQ 的人来说都不是一个大规模问题吗?是这样吗?

标签: .net memory-leaks static delegates


【解决方案1】:

不,没什么好担心的。将委托传递给方法很好,(除非该方法将委托无限期地存储在某处)。

有问题的是静态事件(或长寿命对象上的事件,例如单例)。如果您不取消订阅这些,则该事件可以使对象永远保持活动状态。例如:

// this object is meant to be short-lived
var obj = new SomeType();

// some static event
MyUtility.SomeEvent += { obj.Foo(); };

现在MyUtility 上的静态事件会阻止新的SomeType 实例被收集,直到该事件订阅被删除......它可能永远不会,因为它是一个匿名方法(需要巫术取消订阅) .

【讨论】:

  • 感谢 Marc,进一步考虑这一点,我猜想一旦包含委托的堆栈帧从堆栈中弹出,调用对象将无处可植于静态对象。无论如何,谢谢您的确认。投赞成票并打勾。
  • @johnc 实际上,在大多数情况下,它是 stack 具有引用的,它是瞬态的。只有当引用被放在从未收集过的东西上时它才会成为问题(例如:静态/单例事件)
【解决方案2】:

这不会导致内存泄漏。只要您不将委托引用保存在静态变量中,那么在方法完成后可以收集委托所有者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 2018-02-14
    • 2018-05-07
    • 2020-03-27
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多