垃圾收集,并处理问题。感谢一些聪明的帮助

时间:2013-12-03 14:31:51

标签: c# object garbage-collection dispose finalizer

Dispose方法是否使用垃圾收集器来清除资源? 使用Dispose而不是终结器有什么好处?
我已经搜索了答案,但到目前为止还没有很好地解释它 谢谢。

4 个答案:

答案 0 :(得分:3)

Dispose()是一种常规方法 它与垃圾收集器无关。

调用Dispose()之类的方法可以释放垃圾收集器不知道的非托管资源,例如本机文件句柄。
您也应该在终结器中执行此操作,以便在呼叫者忘记呼叫Dispose()时不会泄漏。但是,调用Dispose()允许它们立即释放,而不是等待垃圾收集器处理你的对象。

如果您的对象包含其他对象,而这些对象又具有非托管资源,则应该实现Dispose(),但不应该实现终结器。 Dispose()允许您的呼叫者立即处置更深层次的非托管资源,但您没有任何东西可供终结者使用。 (非管理资源应该由内部终结器发布)

要彻底实现这一点,请使用Dispose(disposing) pattern,它清楚地描述了托管托管和非托管资源的位置。

答案 1 :(得分:2)

  

dispose()方法是否使用垃圾收集来清除资源?

没有。 Dispose()用于释放非托管资源(通常)。它与GC没有任何关系。

请参阅:IDisposable interface

  

此界面的主要用途是以释放非托管   资源即可。垃圾收集器会自动释放内存   在不再使用该对象时分配给托管对象。   但是,无法预测何时进行垃圾收集   发生。此外,垃圾收集器不知道   非托管资源,如窗口句柄,或打开文件和流。

垃圾收集器调用对象的终结器(析构函数),如果该对象实现IDisposable,则终结器可以调用Dispose(false)

答案 2 :(得分:0)

为了按照指定行事,某些对象需要外部实体代表他们做事。在某些情况下,外部实体将能够在方法返回之前执行所有必要的操作。然而,在其他情况下,一种方法需要在要求外部实体继续做某事之后才返回,直到另行通知为止(但没有给出这样的通知)。因此,该对象有责任让外部实体知道何时不再需要其服务。

IDisposable的目的是提供一种标准化的方式,通过该方式可以告诉对象“您的服务将不再需要,所以如果您已经要求任何外部实体开始代表您这样做,那么你可以反过来用它来满足你的顾客,你应该告诉他们不要这样做。“它通常不会释放任何内存(除非外部实体保留了一些内存以帮助它满足对象的需要),并且在许多情况下不需要实际执行任何操作(如果没有外部实体代表某些内容执行任何操作)对象,没有人需要被告知停止代表它行事。)

终结器的存在主要是为了处理实现IDisposable的对象可能在没有调用其处置方法的情况下被抛弃的可能性。它有效地告诉一个对象“看起来好像你已经被遗弃了,所以你应该清理一下”。尽管Finalize可以作为“安全网”,但它不应被视为可靠;通常情况下,如果一个具有终结器的物体被错误地放弃,那么终结器将“有时”运行,但通常不能保证及时性。因此,当一个要求实体代表它做某事的对象不再需要时,应立即告知(通过Dispose)而不是放弃。在一个写得很好的程序中,很少有终结器可以运行。

答案 3 :(得分:0)

这里的许多答案都集中在释放非管理资源 - 这确实是Dispose的作用。 同样重要的是要注意这种情况(必须处理原始的manged资源,即os文件句柄,套接字句柄等)非常罕见。在几乎所有情况下,我们都通过MANAGED对象处理这些资源 - 他们自己实施IDisposable以释放他们的资源 所以实际上编写dispose的常见原因并不是释放什么资源,而是释放资源。即一般我们编写Dispose,因为我们的对象包含控制资源的(托管)成员(例如TCPClient)持有一个套接字)。通过使用IDispose,我们允许本类用户控制何时释放MANAGED资源 - 通过应用using语句或明确调用Dispose