垃圾收集干扰对象创建?

时间:2015-03-25 13:37:22

标签: c# wpf garbage-collection

我正在开发一个WPF应用程序,其中包含一个DevExpress DocumentGroup,其中包含不同的面板,其中包含Pages。其中一个名为' overview'我用的是一张非常大的图片(10.000 x 7.000)作为背景。当我单击一个按钮创建一个包含概述的新面板时,我可以在任务管理器中看到如何使用越来越多的内存。

关闭概览面板后,内存使用量会有所下降,但绝不会像打开Page之前那样低。如果我打开和关闭页面几次内存使用率达到一个临界点,程序冻结并且从不加载概述。在taskmanager中看一下,内存使用量大幅下降。

垃圾收集器不应该在我关闭后删除我的概述实例,因此删除对我的概述的所有引用?垃圾收集者是否决定收集'而我正处于创建新概述页面的过程中,因此中断了创建?

2 个答案:

答案 0 :(得分:2)

你咬的是Fundamentals of Garbage Collection

中的这一部分
  

通常,大型对象堆不会被压缩,因为复制   大型物体会造成性能损失。但是,从开始   在.NET Framework 4.5.1中,您可以使用   GCSettings.LargeObjectHeapCompactionMode属性压缩大   对象堆按需。

因此,您的图像会立即提升到Gen 2对象池,并且还会将更多内容添加到大对象堆中。当收集器以工作站模式运行时(Windows 7,8等机器的默认设置,Windows Server版本的服务器),这些对象将永远不会被收集或压缩。
我非常确定强制GC.Collect()对你没有任何作用,因为收集器(在工作站模式下)将忽略大对象堆。

我已经看到这在Windows7计算机上测试了一个繁重的消息处理服务,在几条100k消息之后,应用程序将以内存不足异常终止。 将收集器切换到服务器模式为我解决了这个问题。

从MSDN条目<gcServer> Element: - 将其添加到项目的app.config文件

<configuration>
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

<强>更新
好的,删除终结器,这不是它的用途,它对垃圾收集没有任何影响或负面影响。

调用CG.Collect()并不能保证你会看到内存使用量下降,收集器是一个复杂的野兽并预测它在任何给定情况下会做什么都是愚蠢的事。

在这个阶段你只能做两件事,你可能需要做两件事。

  1. 确保没有对大对象的引用,包括 事件处理程序侦听该对象引发的事件。

  2. 通过内存分析器运行它,就像上面评论中提到的ANTS一样。

答案 1 :(得分:1)

通过MSDN about the fundamentals of GC阅读,它显示以下内容:

当满足下列条件之一时,就会发生垃圾收集:

  • 系统物理内存较低。
  • 使用的内存 托管堆上分配的对象超过了可接受的范围 阈。该阈值作为过程不断调整 运行。
  • 调用GC.Collect方法。在几乎所有情况下,你都这样做 不必调用此方法,因为垃圾收集器运行 不断。此方法主要用于独特的情况和 测试

因此,在关闭概述之后,它似乎并没有立即清除内存,正如您似乎期待的那样。 GC会在需要时清除内存。