我想知道在调用Dispose()方法时执行的操作。 Object在Dispose()调用或Dispose()上快速释放所有资源,标记Object已准备好进行垃圾回收。当我们将Object引用设置为NULL时发生了什么。实际上我在.NET 2.0中有Windows表单应用程序。并且我希望在经过一定时间后调用垃圾收集器(例如5分钟后)以收集所有未引用的对象。
答案 0 :(得分:9)
Dispose
通常为frees unmanaged resources owned by the object。调用Dispose
不会触发垃圾回收;当您的对象不再引用它时,就会收集它,就像您从未调用过Dispose
一样。
将对象引用设置为null
只会导致该引用不再指向该对象;你通常不需要这样做(例如,你几乎不需要将局部变量设置为null
)。
您自己也几乎不需要自己触发垃圾回收。您是否看到一个问题,表明您需要每5分钟运行一次垃圾收集,而不是在运行时选择的时候?
答案 1 :(得分:7)
Dispose方法没有什么神奇之处,就像任何其他方法一样。调用Dispose方法不会在后台进行任何清理或更改对象的状态,它只会执行您在方法中所做的操作。它的特殊之处在于它是在IDisposable接口中定义的,因此它是告诉对象清理其资源的标准方法。
在Dispose方法中,对象应该处理所有非托管资源,例如数据库连接和Font对象。
当您释放对象时,您不必担心任何托管资源。类似于字节数组的结构完全由垃圾收集器处理,您可以在放开时将其保留在对象中。您不需要设置对null
的任何引用,当您不再使用对象时,垃圾收集器将找到删除它及其引用的任何对象的最佳时间。
垃圾收集器通常在单独使用时效果最佳,没有必要在收集未使用的对象时告诉它。当它应该完成时它会自己弄明白,并且通常它会比你更好,因为它可以访问大量有关内存状态和代码所没有的机器状态的信息。
您可能会觉得应该尽量减少内存使用量,但这本身并没有优势。计算机不能更好地工作,因为它有更多的可用内存。相反,如果你的代码试图进行清理,或强迫垃圾收集器做任何事情,那么当它应该忙于做更重要的事情时,它正在进行清理。如果需要,垃圾收集器将清理未使用的对象。
答案 2 :(得分:2)
如果某个对象没有对其进行引用,则该对象可以使用它。如果它在一段时间内对其进行了引用(由垃圾收集器管理),它就开始通过所谓的“世代”进行推广。
Dispose方法只是一种模式(不是语言强加的对象删除机制),表示该对象现在可以清理任何非托管资源,关闭任何连接等。
Dispose方法执行的操作完全由程序员控制,众所周知,它可能什么都不做。
垃圾收集器对Dispose方法没有兴趣 - 但是通过Finalizer,可能无论如何都会调用对象的Dispose逻辑 - 遵循IDisposable模式的人会将终结器实现为最后一个“你忘了调用Dispose了我会在GC杀死我“清理资源的方式”之前做到这一点。
请注意,如果未调用Dispose,则任何托管资源最终都将进行GC(除非保留引用)。但是,只有在整个应用程序进程完成时才会回收非托管资源(以及仍保留引用的任何托管资源)。
答案 3 :(得分:1)
这里的其他人已经充分回答了“IDisposable
如何与垃圾收集器进行交互”和“何时应该问GC.Collect
”部分问题。
我有一篇博文,详细介绍when you should set variables to null
to help the garbage collector(问题的第三部分)。简短的回答是“几乎从不,除非它是一个静态变量。”
答案 4 :(得分:0)
自动垃圾收集的重点是您不必担心释放对象。不要试图“帮助”垃圾收集器。
对象在超出范围后最终被垃圾收集。无法手动“释放”对象或将其标记为更快的垃圾回收。请记住哪些对象在范围内(或从范围内的对象引用)。
Dispose方法只是一种方法。它与垃圾收集无关。 “Dispose”恰好是using
语句调用的方法的名称:
using (var x = expr) { ... }
基本等同于
var x = expr;
try { ... } finally { x.Dispose(); }
答案 5 :(得分:0)
对于您的类对象,您要定义Dispose
将执行的操作。您实现了包含方法Dispose
的{{3}}接口,并且取决于实现。但通常Dispose
的目的是释放资源(托管/非托管)并使对象成为GC
的候选对象。
关于设置null
我们可以说它没用。它只是注意到没有对象的引用,因此它成为GC
的候选者,但同样不需要将null
设置为GC
可以发现没有引用没有那个的对象..
为了调用Collect
,我们不建议(直到你有极端的需要和争论),因为GC已经过优化,以便知道Collection
的正确时间。
答案 6 :(得分:0)
如果正确实施,Dispose将处置它实现IDisposable的任何托管资源,并立即释放任何非托管资源。当没有对象的引用时,对象本身将被标记为集合。通常,对象在using块中使用,并且在块的末尾自动调用Dispose方法,对象超出范围并且当时有资格进行收集。
在一般情况下,通过直接与垃圾收集器交互,您将导致比解决更多的问题。如果您认为必须这样做,则更有可能是您需要重构解决方案的信号 - 即,您的类之间存在太多耦合,导致对象保持活动的时间超过必要时间。更清洁的体系结构可以使系统更好地管理对象生命周期。
有关如何implement the IDisposable pattern的讨论,请参阅MSDN。
答案 7 :(得分:-1)
当调用Dispose()时,该对象仅标记为垃圾回收。 < - 更新:这是错误的。 Dispose()实际上并没有做任何事情,除非你或编译器调用它(当在'using'结构中使用时)。
来自MSDN -
在大多数情况下,垃圾收集器 可以确定最佳表演时间 一个集合,你应该让它运行 独立。有罕见的 强制收集的情况 可能会改善您的应用程序 性能。在这些情况下,你可以 通过使用来诱导垃圾收集 收集方法强制垃圾 集合
请参阅此文章 - http://msdn.microsoft.com/en-us/library/bb384155.aspx
答案 8 :(得分:-1)