为什么我的窗户没有收集垃圾?

时间:2011-01-25 01:56:48

标签: c# wpf

我有一个标准的CRUD应用程序,可以处理相当大量的数据。不同的窗口使用Linq-To-SQL访问不同的表,每个窗口基本上都有一个网格,其中的单元格绑定到我正在显示的对象。

这是一个非常标准的用例,说明了正在发生的事情:

  1. 打开窗口A
  2. 关闭窗口A - 窗口A现在仍在内存中但不再可见。
  3. 打开窗口B
  4. 关闭窗口B - Windows A和B现在都在内存中,两者都不可见。
  5. 打开窗口C
  6. 当为Window C检索数据时,将释放Window A的资源。
  7. 所以在任何时候我都会在内存中保存2-3个窗口,而我应该拥有的只有一个窗口。我甚至为这些窗口的关闭事件添加了处理代码,它将我能想到的所有引用都设置为null。

    我尝试使用ANTS内存分析器,我注意到每个窗口都设置为GC根目录。有没有办法禁用此行为或以某种方式强制GC从这些窗口收集?

    谢谢!

    PS:我已经检查了this link但它没有解决问题。

    编辑:问题是用户正在获取System.OutOfMemoryExceptions。

2 个答案:

答案 0 :(得分:2)

一般情况下,GC都有自己的生命。通过释放资源,您只需通知它不再需要资源。由于性能限制和特定于平台的实现,垃圾收集需要一些时间。

是什么让开发人员生活更轻松 - 有时会伤害性能。这就是为什么在C / C ++中可以拥有你想要的内存和新/删除。甚至那里有游泳池和其他技术,因为新/删除并不便宜。

最后,您需要确定架构中的问题。为什么这对你来说是个问题?记忆力不足?交换?在本地还是在服务器上?等

答案 1 :(得分:2)

我能够通过两次更新解决这个问题。首先,我在我的孩子的窗户上使用Telerik控件。 Telerik控件必须跟踪根视觉,因此如果它们仅在子窗口上实例化,则在每个实例化时,它们假定子窗口是根视觉并为其分配静态引用。通过在我的主应用程序窗口上实例化telerik控件,该窗口被设置为静态引用中的根视觉。

我做的第二个更新是将每个子窗口的所有者分配为我的主应用程序窗口。执行此操作并进行分析后,我发现子窗口不再被设置为GC根。

现在我的子窗口在关闭后会自动收集垃圾,只要为另一个窗口请求新内存。