我知道所有实现IDisposable
接口的对象都应该在不再需要时立即被处理,以释放其非托管资源使用的内存。
我的问题与我所知道的会一直存在直到主机进程本身终止的对象有关。如果我对它们进行处理或不进行处理是否会有任何区别?在进程终止时是否有可能未释放内存?GDI对象呢?即使它们没有被处理,GDI句柄也会在进程终止时被释放吗?
我完全理解,无论如何处理所有对象都是良好的实践。我只是出于好奇而问。
我知道所有实现IDisposable
接口的对象都应该在不再需要时立即被处理,以释放其非托管资源使用的内存。
我的问题与我所知道的会一直存在直到主机进程本身终止的对象有关。如果我对它们进行处理或不进行处理是否会有任何区别?在进程终止时是否有可能未释放内存?GDI对象呢?即使它们没有被处理,GDI句柄也会在进程终止时被释放吗?
我完全理解,无论如何处理所有对象都是良好的实践。我只是出于好奇而问。
这取决于所涉及的对象(资源)。
当进程终止时,所有未管理的内存、文件句柄和其他操作系统资源将被释放,即使相关的 finalizer 未能运行。
但是我不确定数据库句柄、命名互斥体等是否也会被释放。
因此,在您认为不需要调用 Dispose() 之前,您必须了解资源类型以及它与进程的关系。最好还是按照一般原则调用 Dispose()。
但这是一个理论上的论点,大多数类将使用 SafeHandle : CriticalFinalizerObject
。因此,我不认为这是一个真正的实际问题。
Dispose
可以调用 GC.SuppressFinalize
来表示不再需要终结器。(编辑:实际上,我认为每个对象都有一个终结器,但默认情况下它什么也不做。) - user743382Finalize
方法的对象时,会创建一种特殊的弱引用,并将其存储在覆盖 Finalize
方法的对象列表中,同时存储其他一些簿记信息。即使对象立即调用 GC.SuppressFinalize()
自身,也无法避免系统设置该引用所需执行的工作,也不会释放簿记信息,直到对象本身被收集。未覆盖 Finalize
方法的对象永远不会放置在列表上,并且通常不需要创建簿记信息。 - supercat根据设计,IDisposable可用于使程序提前释放非托管资源,比终结器更早地释放。终结器在进行垃圾回收时通常会在稍后的时间运行,时间相当不确定。你无法预测何时会发生。
在程序退出时进行处理没有意义,因为终结器保证会在AppDomain卸载和进程关闭之前运行。
话虽如此,有一些滥用IDisposable的代码实际上期望你调用它。但这通常是基于“using”语句的,所以不太可能遇到这种情况。