GC,Finalize()和Dispose之间的关系是什么?

Los*_*ost 21 .net c#

GC用于托管对象,Finalize用于非托管对象,这是我一直在阅读的内容.Dispose是隐式的,Finalize是Explicit是我一直在阅读的内容.有人可以给我一个模块的例子,其中所有三件事由于不同的原因被使用了吗?

Bri*_*sen 30

GC是垃圾收集.它是自动内存管理,用于处理托管堆上分配的对象的清理..NET GC采用标记和扫描算法.当垃圾收集发生时,它基本上将要清理的堆部分中的所有对象都视为可恢复的.然后它会经历一个标记过程,在那里扫描根.即它识别应用程序仍在使用的对象.完成后,剩余的对象有资格进行清理.堆可以作为清理的一部分进行压缩.

Dispose和finalizer方法都提供了清理资源的选项,这些选项不由 GC处理.例如,这可以是原生句柄等.它们与回收托管堆上的内存无关.

必须在实现的类型上显式调用Dispose IDisposable.它可以通过Dispose()方法本身或通过using构造来调用.GC不会自动调用Dispose.

另一方面,终结器或析构函数(如语言规范所称)将在对象符合清除条件后的某个时间自动调用.Finalize方法在专用线程上顺序执行.

Dispose()允许确定性清理资源,而终结者可以在用户不打电话时充当安全网Dispose().

如果类型实现了终结器,则实例的清理会被延迟,因为必须在清理之前调用终结器.即,它将需要额外的收集来回收该类型的实例的内存.如果类型也实现了IDisposable,则可以调用Dispose方法,然后实例可以从finalization中删除它自己.这将允许清理对象,就好像它没有终结器一样.

如果你想深入研究这一点,我建议你通过C#by Jeffrey Richter进行CLR.这是一本很棒的书,它涵盖了所有的血腥细节(我遗漏了一些细节).新的第3版刚刚发布.


Ree*_*sey 11

.NET的一个好处是垃圾收集器.在许多语言中,每一块内存都必须由开发人员管理 - 任何分配的内存最终都应该被释放.在.NET(C#)中,垃圾收集器(GC)将负责为您释放内存的过程.它跟踪对象的使用情况,在它们变为"无根"之后(即:应用程序中没有直接或间接地引用该对象的引用),对象的内存会自动清除.

处理,或更具体地说,IDisposableDispose模式用于与GC分开处理资源.由于各种原因,需要明确清理一些资源.这包括使用"本机"API(其中.NET不知道已分配的内存),使用包装本机句柄的资源等.为了清楚地处理它,您实现IDisposable了Dispose模式.

当对象即将被垃圾收集器收集时,将在对象上进行终结.这提供了一个"安全网",如果比理想时间稍晚,那么应该已经处理过的物体仍然可以被清理干净.通过实现终结器,您可以保证始终释放非托管资源.

大多数样本的问题是使用IDisposable有多种原因,并且正确的实现因您使用它的原因而异.例如,如果直接包装本机资源,则应该实现终结器,但如果封装另一个IDisposable类型,则不需要终结器,即使您仍应实现IDisposable.为了解决这个问题,我在博客上写了关于IDisposable和最终定稿的文章,描述了你使用IDisposable的多种原因,以及不同的原因.


Mar*_*ann 8

您可能只想阅读我认为关于IDisposable,终结器和垃圾收集的权威文章,Shawn Farkas的CLR Inside Out:Digging into IDisposable.

这篇文章对这个问题毫无疑问.

  • 嗨Mark,Dipose()和其他两个之间的区别是我所理解的,但我正在努力的是理解Finalize()和垃圾收集器()之间的区别.因为我遇到很多文章,作者我说GC最终使用Finalize()消灭对象.那么在类定义中保持Finalize()与不保留一个之间有什么区别,因为即使我没有在我的类定义中保留Finalize(),GC也最终调用Finalize()来消除未使用的对象. (2认同)