【发布时间】:2017-11-21 13:22:01
【问题描述】:
假设我有一个如下所示的 C# 类:
public class MyClass {
public SomeObject TheObject { get; }
public MyClass() {
TheObject = new SomeObject();
TheObject.MyEvent += MyEventHandler;
}
private void MyEventHandler() {
// some code
}
}
该类创建一个名为 TheObject 的 SomeObject 类型的内部对象,并为该对象上的事件添加一个事件处理程序。
由于 TheObject 是一个公共属性,这意味着任何其他代码都可以维护指向该对象的指针;反过来,这将使 MyClass 类型的对象保持活动状态,因为 TheObject 以事件处理程序的形式具有指向 MyClass 的指针。
所以,我认为保护此代码免受此事件影响的唯一方法是向 MyClass 添加终结器:
public ~MyClass() {
TheObject?.MyEvent -= MyEventHandler;
}
这太糟糕了,因为终结器会将 MyClass 类型的对象提升到下一代 GC,但我是否正确地说这是避免这种潜在内存泄漏的唯一方法?
【问题讨论】:
-
在 MyClass 中实现 IDisposable?
-
@Jacek 我会让 SomeObject 实现 IDisposable ,因为其他类也可以包含对它的引用,因此当不再需要它时,它可以被 GC 处理和收集
-
是的,所以你可以在 SomeObject 中实现 IDisposable 并利用这个答案stackoverflow.com/a/447960/2811109
-
我在这个问题中看到了“C++ 心态”。它是 references 而不是 C# 中的 pointers,虽然它们有相似之处,但它们是不同的概念。当一个对象由于垃圾回收而被移动时,内部指针会被调整,而引用保持不变。此外,C# 终结器与 C++ 析构函数不同。终结器用于释放 unmanaged 资源。除非您直接与底层平台/操作系统交互,否则这种情况很少见。内存由垃圾收集器处理,但要实现 C++ 析构函数可以执行的任何其他清理,您可以使用
IDisposable。
标签: c# memory-leaks garbage-collection