如果处理失败,是否有可能发生永久性内存泄漏?

Is it possible to have permanent memory leak if failed to dispose?

我知道用 using 包裹每个 IDisposible 对象总是一个好习惯。但是,如果我不这样做,是否有可能像 C++ 那样造成永久性内存泄漏? (永久是指应用程序的生命周期)

我知道 GC 很难处理 COM 和本机资源,但假设我只使用托管代码。没有 COM,没有不安全,只有内置包和托管代码。是否有任何 IDisposible 即使在变量超出范围后 GC 也无法收集的?

是的。当GC回收了一个对象,那么这个对象的finalizer就是运行。在大多数 IDisposable 的实现中,IDisposable.Dispose() 是从终结器调用的,这意味着对象将在垃圾回收时被释放。

然而,有时情况并非如此。比如我前段时间SharpDX library are not disposed in their finalizers, so if you do not dispose them, then the native objects that they represent (in this case, graphics resources) will not be cleaned up and you will end up with a memory leak. This is actually the source of 里的很多对象

编辑:我没有看到您提到没有非托管资源。在那种情况下,不。所有不依赖于非托管代码的 C# 代码都必须依赖于 BCL,这不容易造成内存泄漏。

是的,这是可能的。一个常见的问题来源是计时器,当计时器未被处置时,它会保留对您的回调的引用并使您的 class 实现回调和所有相关数据永远存在。

除了未管理的对象之外,另一个非常常见的来源是事件注册,如果不使用弱事件模式,这些事件注册将在 dispose 方法中取消注册。这可能会变得非常难以管理,这就是 WPF 完全依赖弱事件来解决生命周期问题的原因。 WPF Windows 没有 Dispose 方法。生命周期完全由垃圾收集器管理。

另一方面,如果您使用的是 WinForms,您很快就会注意到如果您忘记在某些 windows 上调用 Dispose 会发生什么...