我在WPF应用程序中是否应该手动强制进行垃圾回收?

12

我刚刚在整理我的WPF应用程序中的一些内存泄漏问题。为此,我使用了CLR分析器和观察Windows任务管理器中的进程统计信息。我的基本测试是确保关闭某个窗口后,它不会仍然停留在内存中。

我对Windows开发还有些陌生,最初我感到困惑的是,在一个简单的测试应用程序中,似乎无论如何,我的窗口在关闭后总是停留在内存中。但我最终弄清楚了,这并不意味着存在内存泄漏,而只是它们尚未被垃圾收集。因此,我不得不在我的主窗口中创建一个按钮,将其连接到包含手动强制进行垃圾收集代码的事件处理程序中。通过手动进行垃圾收集,我可以完成内存泄漏测试,并将其全部解决。

但这让我思考 - 是否曾经需要手动强制进行垃圾收集?

看着我的应用程序的内存消耗越来越多当我打开和关闭窗口时,这让我感到痛苦。当然,最终,垃圾回收自动运行,这一切都得到了解决。但是,关闭这些重型窗口后手动垃圾回收似乎是个好主意。但这有意义吗?我觉得除了测试之外,我们不应该强制进行垃圾回收 - 只需让系统自行处理。

欢迎发表您的想法。

6个回答

13

感谢大家的反馈。我会按照你们的建议去做,让系统处理它应该处理的内容!

我实际上已经在我手头的一本.NET框架的书中找到了一个很好的答案。它说:

.NET垃圾回收器的整个目的是代表我们管理内存。然而,在极为罕见的情况下,可能有益于使用GC.Collect()编程方式强制进行垃圾回收。具体来说:

  • 当您的应用程序即将进入一段您不希望被可能的垃圾回收干扰的代码块时。
  • 当您的应用程序刚刚完成分配大量对象,并希望尽快删除所获取的内存时。

5

在任何.NET应用程序中,强制手动进行垃圾回收都不是一个好的做法。GC应该比我们更聪明(实际上它确实是很聪明的)。不幸的是,如果存在内存泄漏,即使强制调用GC也无济于事。


3
“如果存在内存泄漏,即使强制调用GC也无济于事”,这是一个非常好的观点……泄漏的对象不会成为垃圾回收的候选对象。 - NateTheGreat

3

我同意你的观点两面都有 :-). 通常我认为写.NET运行时的人比我聪明,对垃圾回收的理解比我更好,所以我不去管它。

我见过一些人试图通过强制进行垃圾回收来改善性能,但从未有确凿的证据表明这是有帮助的。


2

我唯一使用GC.Collect的时候是为了快速了解有多少内存可以被回收。

否则这是没有用的,因为直到现在GC比我聪明。


2

我认为你应该阅读这篇文章:WPF内存分配的秘密。虽然不是关于你的问题,但它对于理解WPF行为非常有价值。


0

虽然手动调用GC.Collect是无用的,但当您知道您已经完成了对更大对象的使用时,您可以手动调用Dispose,这样即使您在代码中没有理由地保留对它们的引用(不规范),至少它们的析构函数被调用并且(如果比前面提到的不规范的代码编写得更好)实际上不会占用太多内存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接