使用垃圾收集?

我想知道在调用Dispose()方法时执行了什么操作。 Object在Dispose()调用或Dispose()上快速释放所有资源,标记Object已准备好进行垃圾回收。 当我们将Object引用设置为NULL时发生了什么。 实际上我在.NET 2.0中有Windows表单应用程序。 并且我希望在经过一定时间后调用垃圾收集器(例如5分钟后)以收集所有未引用的对象。

Dispose方法没有什么神奇之处,就像任何其他方法一样。 调用Dispose方法不会在后台进行任何清理或更改对象的状态,它只会执行您在方法中所做的操作。 它的特殊之处在于它在IDisposable接口中定义,因此它是告诉对象清理其资源的标准方法。

在Dispose方法中,对象应该处理所有非托管资源,如数据库连接和Font对象。

释放对象时,您不必担心任何托管资源。 类似于字节数组的结构完全由垃圾收集器处理,您可以在放开时将其保留在对象中。 您不需要设置任何对null引用,当您不再使用对象时,垃圾收集器将找到删除它及其引用的任何对象的最佳时间。

当你不管它时,垃圾收集器通常效果最好,没有必要在收集未使用的对象时告诉它。 当它应该完成时它会自己弄明白,并且通常它会比你更好,因为它可以访问大量有关内存状态和代码所没有的机器状态的信息。

您可能会觉得应该尝试将内存使用率保持在较低水平,但这本身并没有优势。 计算机无法更好地工作,因为它有更多的可用内存。 相反,如果您的代码尝试进行清理,或者强制垃圾收集器执行任何操作,那么它应该在忙于执行更重要的操作时进行清理。 如果需要,垃圾收集器将清理未使用的对象。

Dispose通常释放对象拥有的非托管资源 。 调用Dispose不会触发垃圾回收; 当您的对象不再引用它时,就会收集它,就像您从未调用过Dispose

将对象引用设置为null只会导致该引用不再指向该对象; 您通常不需要这样做(例如,您几乎不需要将局部变量设置为null )。

你自己也几乎不需要自己触发垃圾收集。 您是否看到一个问题,表明您需要每5分钟运行一次垃圾收集,而不是在运行时选择的时间点?

如果GC没有对其进行引用,则该对象可用于GC。 如果它在一段时间内(由垃圾收集器管理)对其进行了引用,则它开始通过所谓的“代”进行提升。

Dispose方法只是一种模式(不是语言强加的对象删除机制),表示对象现在可以清理任何非托管资源,关闭任何连接等。

Dispose方法执行的操作完全由程序员控制,众所周知,它可能什么都不做。

垃圾收集器对Dispose方法没有兴趣 – 但是通过Finalizer,可能无论如何都会调用对象的Dispose逻辑 – 遵循IDisposable模式的人将终结器实现为最后一个“你忘了调用Dispose所以我会在GC杀死我“清理资源的方式”之前做到这一点。

请注意,如果未调用Dispose,则任何受管资源最终都将进行GC(除非保持引用)。 但是,只有在整个应用程序进程完成时才会回收非托管资源(以及仍保留引用的任何托管资源)。

这里的其他人已经充分回答了“ IDisposable如何与垃圾收集器进行交互”和“何时应该调用GC.Collect ”部分问题。

我有一篇博文,详细介绍了何时应将变量设置为null以帮助垃圾收集器 (问题的第三部分)。 简短的回答是“几乎从不,除非它是一个静态变量。”

自动垃圾收集的关键是你不必担心释放对象 。 不要试图“帮助”垃圾收集器。

对象在超出范围后最终被垃圾收集。 无法手动“释放”对象或将其标记为更快的垃圾回收。 请记住哪些对象在范围内(或从范围内的对象引用)。

Dispose方法只是一种方法。 它与垃圾收集无关。 “Dispose”恰好是using语句调用的方法的名称:

 using (var x = expr) { ... } 

基本上相当于

 var x = expr; try { ... } finally { x.Dispose(); } 

如果正确实施,Dispose将处置它实现IDisposable的任何托管资源,并立即释放任何非托管资源。 当没有对象的引用时,对象本身将被标记为集合。 通常,对象在using块中使用 ,Dispose方法在块的末尾自动调用,对象超出范围并且当时有资格进行收集。

在一般情况下,通过直接与垃圾收集器交互,您将导致比解决更多的问题。 如果您认为必须这样做,则更有可能是您需要重构解决方案的信号 – 即,您的类之间存在太多耦合,导致对象保持活动的时间超过必要时间。 更清洁的体系结构可以使系统更好地进行对象生存期管理。

有关如何实现IDisposable模式的讨论,请参阅MSDN。

对于您的类对象,您正在定义Dispose将执行的操作。 您实现IDisposable接口,其中包含方法Dispose并依赖于实现。 但一般来说, Dispose的目的是释放资源(托管/非托管)并使对象成为GC候选对象。

关于设置null我们可以说它没用。 它只是注意到没有对象的引用因此它成为GC候选者,但是再次没有必要设置null因为GC可以发现没有那个没有对象的引用。

对于调用Collect ,不建议(直到你有极端的需要和参数),因为GC已经过优化,知道什么是Collection的正确时间。

如果您确实想强制使用垃圾收集:

 GC.Collect(); 

请查看此post,了解您不应使用它的原因:

使用GC.Collect()有什么不对?

调用Dispose()时,该对象仅标记为垃圾回收。 < - 更新:这是错误的。 Dispose()实际上并没有做任何事情,除非你或编译器调用它(当在'using'结构中使用时)。

来自MSDN –

在大多数情况下,垃圾收集器可以确定执行集合的最佳时间,您应该让它独立运行。 强制收集可能会提高应用程序性能的情况很少见。 在这些情况下,您可以使用Collect方法强制垃圾回收来诱导垃圾回收

请参阅此文章 – http://msdn.microsoft.com/en-us/library/bb384155.aspx