【问题标题】:Do a self handled event prevent the instance from being garbage-Collected?自我处理的事件是否会阻止实例被垃圾收集?
【发布时间】:2009-05-20 15:47:50
【问题描述】:

我看了Do event handlers stop garbage collection from occuring?这个问题的答案,但是当发布者是目标时会发生什么?

更具体地说,我正在为 WPF 应用程序使用 MVVM 设计。模型视图类在每次更改时都会引发 NotifyPropertyChanged。在某些类中,我需要在修改某些内容时调用一个方法。

我想这样做:

this.PropertyChanged += this.MyHandler;

这个实例会被 GC 销毁吗?

【问题讨论】:

  • 为什么不直接覆盖 OnNotifyPropertyChanged?

标签: c# .net events mvvm garbage-collection


【解决方案1】:

GC 查找并查看对对象的任何引用当前是否植根于应用程序。处理像上面这样的循环引用是足够聪明的。

此外,它足够聪明地处理您有两个对象 A 和 B 的情况,并且:

A.Event += B.Handler; 
B.Event += A.Handler;

如果 A 和 B 都超出范围,GC 足够聪明,可以找到并清理这两个对象,即使它们相互订阅。但是,如果一个单独的对象(正在使用)引用其中任何一个,它将阻止两者都被收集。

与引用计数解决方案相比,这是真正的 GC 解决方案的主要优势之一。引用计数将无法收集到这一点,但 .NET gc 会完美地处理它。

【讨论】:

    【解决方案2】:

    是的,GC 会清理对象,因为在引用它的对象之外没有任何东西。

    GC 获取根级别的所有引用(静态字段、每个线程堆栈上的引用等),然后从这些跳转到这些可能引用的对象,然后跳转到这些对象可能引用的对象等等。在此过程中,它将每个对象标记为“不被收集”。一旦它咀嚼过它们,任何尚未标记为“不被收集”的东西都将被收集起来。

    当您遵循这一点时,GC 无法从根目录获取您的对象,因此它将被收集。

    【讨论】:

      【解决方案3】:

      是的,GC 足够智能,可以确定循环引用并收集所涉及的对象。

      它甚至会在多个对象上处理它,因此如果 objectA 正在侦听 objectB 上的事件,而 objectB 正在侦听 objectA 上的事件,前提是它们都未被引用,GC 会发现它可以将它们收集在一起。

      (我能快速找到的最佳参考是另一个 SO 问题 here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-22
        • 1970-01-01
        • 2015-10-08
        • 2015-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多