自处理事件是否会阻止实例被垃圾回收?

时间:2022-04-15 00:24:36

i read the answer of the question Do event handlers stop garbage collection from occuring?, but what happens when the publisher is the target ?

我读了问题的答案Do事件处理程序是否阻止垃圾收集?但是当发布者是目标时会发生什么?

To be more specific, i am using MVVM design for a WPF app. Model-View classes raise a NotifyPropertyChanged on every change. In some classes, i need to call a method when something is modified.

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

I would like to do this:

我想这样做:

this.PropertyChanged += this.MyHandler;

Will this instances be destroyed by the GC ?

这个实例会被GC破坏吗?

3 个解决方案

#1


The GC looks and sees if any references to the object are currently rooted in the application. It is smart enough to handle circular references like the one above.

GC查看并查看对象的任何引用当前是否已根植于应用程序中。它足够聪明,可以像上面那样处理循环引用。

In addition, it is smart enough to handle the case where you have two objects, A, and B, and:

此外,它足够聪明,可以处理有两个对象A和B的情况,以及:

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

If A and B both go out of scope, the GC is smart enough to find and clean both of these objects, even though they subscribe to each other. However, if a separate object (in use) refers to either, it will prevent both from being collected.

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

This is one of the main advantages to a true GC solution, when compared to reference counting solutions. Reference counting will fail to collect this, but the .NET gc will handle it perfectly.

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

#2


Yes the GC will clean the object up since there is nothing external to the object referencing it.

是的,GC将清理对象,因为引用它的对象没有任何外部。

The GC takes all the references held at root level (static fields, references on each threads stack etc.) and leaps from these to objects that these may reference and then to objects the those objects may reference and so on. As it goes it marks each object as "not to be collected". Once it has munched through them anything not yet marked as "not to be collected" is up for collection.

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

When you follow that through there is no way for the GC to get to your object from the root and hence it will be collected.

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

#3


Yes it will, the GC is intelligent enough to determine circular references and collect the objects involved.

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

It will even handle it over multiple objects so if objectA is listening to an event on objectB and objectB is listening to an event on objectA provided they are both otherwise unreferenced the GC will figure out that it can collect both of them together.

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

(Best I can quickly find for a reference is another SO question here)

(我可以快速找到参考,这是另一个SO问题)

#1


The GC looks and sees if any references to the object are currently rooted in the application. It is smart enough to handle circular references like the one above.

GC查看并查看对象的任何引用当前是否已根植于应用程序中。它足够聪明,可以像上面那样处理循环引用。

In addition, it is smart enough to handle the case where you have two objects, A, and B, and:

此外,它足够聪明,可以处理有两个对象A和B的情况,以及:

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

If A and B both go out of scope, the GC is smart enough to find and clean both of these objects, even though they subscribe to each other. However, if a separate object (in use) refers to either, it will prevent both from being collected.

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

This is one of the main advantages to a true GC solution, when compared to reference counting solutions. Reference counting will fail to collect this, but the .NET gc will handle it perfectly.

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

#2


Yes the GC will clean the object up since there is nothing external to the object referencing it.

是的,GC将清理对象,因为引用它的对象没有任何外部。

The GC takes all the references held at root level (static fields, references on each threads stack etc.) and leaps from these to objects that these may reference and then to objects the those objects may reference and so on. As it goes it marks each object as "not to be collected". Once it has munched through them anything not yet marked as "not to be collected" is up for collection.

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

When you follow that through there is no way for the GC to get to your object from the root and hence it will be collected.

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

#3


Yes it will, the GC is intelligent enough to determine circular references and collect the objects involved.

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

It will even handle it over multiple objects so if objectA is listening to an event on objectB and objectB is listening to an event on objectA provided they are both otherwise unreferenced the GC will figure out that it can collect both of them together.

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

(Best I can quickly find for a reference is another SO question here)

(我可以快速找到参考,这是另一个SO问题)