订阅事件但无处理逻辑的类实例是否可被垃圾回收?
问题解答
场景代码
订阅事件但处理方法为空的类:
public class Class1 { public Class1() { SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; } void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) { } }
实例创建方式:
public class Runner { Class1 class1 = new Class1(); }
核心结论
class1是否具备垃圾回收资格,和事件处理方法是否为空完全无关,只取决于是否存在强根引用以及事件的引用类型:
- 当
Runner实例还存活时,class1作为Runner的成员变量被持有强引用,不具备回收资格。 - 当
Runner实例被回收,且没有其他强引用指向class1时,由于SystemEvents.PowerModeChanged采用弱引用存储订阅者,class1会失去所有强根引用,具备垃圾回收资格,会被GC回收。
关键原理
- .NET垃圾回收器判断对象可回收的唯一标准是:对象是否存在有效的强根引用(比如活跃的局部变量、静态变量、其他存活对象的引用等),不会因为事件处理方法为空就忽略引用关系。
SystemEvents是特殊的系统级事件类,它的事件采用弱引用机制存储订阅者,目的是避免订阅者因订阅系统事件而被意外持有,导致内存泄漏。如果是普通的自定义事件(非弱引用),发布者会持有订阅者的强引用,此时只要发布者存活,订阅者即使没有其他引用也不会被回收,但这个场景里不适用。
内容的提问来源于stack exchange,提问作者ispiro
相关产品推荐
相关产品推荐

