Cha*_*thJ 15 .net c# memory-leaks idisposable .net-4.0
我一直在winforms应用程序中修复一些内存泄漏问题,并注意到一些非显式处置的一次性对象(开发人员没有调用Dispose方法).Finalize方法的实现也没有用,因为它没有进入if (disposing)条款.所有静态事件取消注册和收集清除都已放入if (disposing)子句中.如果对象是一次性的,最好的做法就是调用Dispose,但不幸的是,有时会发生这种情况
如果有非托管对象,静态事件处理程序和某些托管集合需要在处理时清除.什么是决定应该进入什么以及什么应该超出if (disposing)条款的方式.
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
disposed = true;
}
}
Run Code Online (Sandbox Code Playgroud)
它表示if (disposing)只有在开发人员显式调用Dispose方法时才能正常执行托管对象.如果已经实现了Finalize方法并且开发人员忘记调用Dispose方法,则通过Finalizer执行的执行不会进入if (disposing)部分.
以下是我的问题.
如果我有静态事件处理程序导致内存泄漏我应该在哪里取消注册?进出if (disposing)条款?
如果我有一些导致内存泄漏的集合,我应该在哪里清除它们?进出if (disposing)条款?
如果我正在使用第三方一次性对象(例如:devExpress winform控件),我不确定它们是托管对象还是非托管对象.假设我想在处理表单时处理它们.我如何知道托管什么以及什么是非托管对象?一次性不说吗?在这种情况下,如何决定应该进入什么以及什么应该超出if (disposing)条款?
如果我不确定某些事情是管理的还是不受管理的,那么处理/清除/取消注册事件的不良后果是if (disposing)什么呢?让我们说它在处置之前检查null?
编辑
我的意思是事件取消注册就像下面这样.Publisher是一个长期存在的实例,下面的行位于订阅者的构造函数中.在这种情况下,订户需要取消注册事件并在发布者之前进行处置.
publisher.DoSomeEvent += subscriber.DoSomething;
Run Code Online (Sandbox Code Playgroud)
“如果(处置)”中应该包含什么
所有托管对象都应该放在 if(diswriting) 子句中。托管对象不应该超出它的范围(这将通过终结执行)。
原因是,如果该类具有析构函数,则垃圾收集器终结过程可以执行 Dispose(false)。通常只有存在非托管资源时才会有析构函数。垃圾收集器的终结没有特定的顺序来执行 Finalize 方法。因此,当终结发生时,其他托管对象可能不在内存中。
| 归档时间: |
|
| 查看次数: |
1767 次 |
| 最近记录: |