我应该在我的WPF应用程序中手动强制垃圾收集吗?

时间:2011-04-22 15:50:49

标签: .net wpf memory-leaks garbage-collection

我刚刚在WPF应用程序中整理了一些内存泄漏。为此,我使用了CLR分析器,以及在Windows任务管理器中查看进程统计信息。我的基本测试是确保当某个窗口关闭时,它仍然没有在内存中停留。

我对Windows开发有点新意,起初我很困惑,因为在一个简单的测试应用程序中,似乎无论如何,我的窗口在关闭后总是留在内存中。但我最终得出结论,这并不意味着存在内存泄漏,而只是简单地说它们还没有被垃圾收集。所以我不得不在我的主窗口中创建一个按钮,该按钮连接到一个事件处理程序,其中包含手动强制垃圾收集的代码。通过手动垃圾收集,我可以完成我的内存泄漏测试,我把它全部排序。

但它让我思考 - 是否需要手动强制垃圾收集?

当我打开和关闭窗口时,我很难看到应用程序的内存消耗量上升。当然,最终,垃圾收集会自动运行并且所有内容都会被整理出来。但在这些沉重的窗户关闭后,手动垃圾收集几乎是个好主意。但有什么意义吗?我觉得测试放在一边,我们不应该强制垃圾收集 - 只需让系统将其排序。

赞赏的想法。

6 个答案:

答案 0 :(得分:9)

感谢您的反馈。我会同意你的建议,让系统关注系统的设计目的!

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

  

.NET垃圾的全部目的   收集器是管理我们的内存   代表。但是,在一些非常罕见的   情况,这可能是有益的   以编程方式强制垃圾   使用GC.Collect()进行收集。   具体做法是:

     
      
  • 当您的应用程序即将进入您没有的代码块时   想要被可能的垃圾打断   集合。
  •   
  • 当您的应用程序刚刚完成分配一个非常大的数字   对象,你希望删除为   尽快获得大部分记忆   可能的。
  •   

答案 1 :(得分:5)

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

答案 2 :(得分:3)

我同意你的观点:-)。我通常采用的方法是,编写.NET运行时的人比我更聪明,并且比我更了解垃圾收集,所以我不管它。

我已经看到了一些人们认为他们通过强制垃圾收集做得很好的情况,但是从来没有任何确凿的证据表明它有所帮助。

答案 3 :(得分:2)

我唯一一次使用GC.Collect就是快速找出准备好收集多少内存。

否则它没用,因为到目前为止,GC比我更聪明。

答案 4 :(得分:2)

我相信你应该阅读这篇文章:Secrets of WPF Memory Allocation。这根本不是关于你的问题,但对于理解WPF行为很有价值。

答案 5 :(得分:0)

虽然手动调用GC.Collect是无用的,但是当您知道已经完成它们时,可以手动调用较大对象上的Dispose,因此即使您在代码中持有对它们的引用无缘无故(马虎),至少他们的析构函数被调用(如果写得比前面提到的草率更好),实际上根本不会占用太多内存。