【问题标题】:Calling Dispose will not clean up the memory used by an object C#? [duplicate]调用 Dispose 不会清理对象 C# 使用的内存? [复制]
【发布时间】:2014-02-06 12:40:38
【问题描述】:

直觉告诉我,Dispose 旨在用于运行用户定义的代码,这些代码会释放不会自动释放的资源 - 例如文件句柄、网络句柄、数据库连接等。

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

他也说

注意,.NET 垃圾收集器是非常不可预测的,它可能会在清理所有符合收集条件的旧实例之前创建对象的一些实例。一种确定方法(无需借助内存分析器)是在终结器中放置一个断点。

i 通过上面的 GC 相关代码释放内存并收集所有未声明的对象或对象超出范围。

他还说永远不要在生产环境中使用上面的GC相关代码,但没有解释原因....所以告诉我如果有人使用下面这些GC相关代码会有什么危害GC.Collect();GC.WaitForPendingFinalizers(); GC.Collect();

无论如何都在寻找深入的知识。谢谢

【问题讨论】:

  • TL;DR:因为拥有自动管理内存的运行时的全部意义在于不必这样做。如果你试图接管你最好知道你在做什么非常好,因为几乎可以肯定你会让事情变得更糟。
  • 如果您确定自己在做什么,切勿自己使用 GC。孩子们不能玩火:)
  • Dispose() 和 GC.Collect() 在很大程度上是不相关的。
  • 所以我知道人们不应该使用但想知道人们何时使用 GC.Collect();和 GC.WaitForPendingFinalizers();谢谢
  • @Jon 同意。但是,在处理您希望最小化 GC 运行等的内存密集型应用程序时,这不是一个好的理念。了解某些东西的工作原理与知道不要弄乱它一样重要:D

标签: c# garbage-collection


【解决方案1】:

GC 永远不会调用 Dispose 方法,只要您在终结器中手动执行此操作

GC 的工作流程很简单,但是很多人都糊涂了,让我们把东西放在他们的位置上

DisposeGC 无关。 Dispose 是一个方法,定义在接口IDisposable 中,与其他接口一样,类可以实现该方法并赋予用户调用该方法的能力。 GC 根本不关注这个接口。 一旦我们在 .NET 中有一个自动内存管理,并且我们知道 GC 做得很好,它会自动清除所有托管资源,因此没有理由提供用户Dispose 清除托管资源的方法。所以一般 Dispose 用于清除非托管资源,但没有人阻止你以取消订阅全局事件为例,或者为嵌套对象调用 Dispose (注意全局事件几乎总是不好的做法:))

另一方面,GC 知道Finalizer,如果Finalizer 存在GC 将对象处理推迟到下一次收集,并在清除内存之前调用Finalizer。为了将配置代码放在一个地方,程序员通常会创建Dispose(bool) 并从FinalizerIDisposable.Dispose 方法中调用此方法。这里需要注意的是,如果调用来自 Finalizer,则不允许访问托管资源,因为 GC 不保证任何处置顺序,并且资源可能已经处于无效状态。这称为dispose pattern

关于生产中的 GC 调用,是的,不推荐,因为一般 GC 做得很好,而且由于 GC.Collect 是昂贵的操作,在我们决定做自动收集之前没有理由打扰 GC 引擎.

【讨论】:

  • 感谢您的回复。你说 GC.Collect 是昂贵的操作。贵的时候介意解释一下吗?谢谢
  • 总是,它从自己的线程开始,使用处理器时间和计算机内存,分析对象图,停止使用这个或那些对象引用的线程,调用终结器等。同意,在.net GC 非常快,但是 GC 对性能的影响不是 0。我记得在 .NET 2 和 .NET 1.1 中,WinForm 应用程序会不时停止响应一段时间(实际上不到一秒),原因是有一个 gossip GC。在以后的版本中,确实,影响并不明显,但也不是 0。
猜你喜欢
  • 2013-01-23
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 2013-04-01
  • 2021-12-10
  • 2013-08-09
  • 1970-01-01
相关资源
最近更新 更多