C# 内存未被收集

C# 内存未被收集,c#,.net,winforms,memory,garbage-collection,C#,.net,Winforms,Memory,Garbage Collection,我正在开发一个MDI风格的winforms应用程序,它将图像作为文档加载。一个文档可以保存许多图像,这些图像存储为位图实例。我发现当我关闭其中一个文档时,GC并没有恢复内存。因此,如果我打开和关闭一个文档几次,内存就会增加很多。尤其是我的应用程序将图像存储为每个通道16位,因此图像非常大。实际上,在打开和关闭文档几次后,它会耗尽内存 起初我以为我有内存泄漏,但结果是,当我关闭一个文档时,如果我调用GC.Collect,那么内存被正确收集,我的问题就消失了 如果GC.Collect正在释放内存,这

我正在开发一个MDI风格的winforms应用程序,它将图像作为文档加载。一个文档可以保存许多图像,这些图像存储为位图实例。我发现当我关闭其中一个文档时,GC并没有恢复内存。因此,如果我打开和关闭一个文档几次,内存就会增加很多。尤其是我的应用程序将图像存储为每个通道16位,因此图像非常大。实际上,在打开和关闭文档几次后,它会耗尽内存

起初我以为我有内存泄漏,但结果是,当我关闭一个文档时,如果我调用GC.Collect,那么内存被正确收集,我的问题就消失了

如果GC.Collect正在释放内存,这意味着我没有泄漏,我的想法对吗?GC不自己做这件事有什么原因吗?在这种情况下,有没有理由不显式使用GC.Collect

  • 如果收集了内存,则是,您没有内存泄漏
  • 您不应该显式地使用对GC.Collect的调用,因为它可能会影响性能。 (仅在必须时才执行此操作)

  • 需要大量空间的对象(我不记得具体有多少)保存在第一代中,而不是第零代中。这就是为什么它们会在相当长的一段时间内保持未收集状态,因为GC不经常收集第一代对象。除非你强迫它

    您是否在调试或发布配置文件中测试此功能?测试此功能时是否附加了调试器?连接调试器时,GC对对象的保留时间要长得多(否则,
    Watch
    窗口将有一半时间失败)。另外,处理完位图对象后,是否正在处理它们?请确保使用using子句包装位图/图像,以便正确处理它们。在发布模式下使用位图/imagesIt时需要小心,不要在调试器中运行。不过,我确实在调试器中做了一些测试——这是一个值得记住的有用提示——感谢所有我的位图被释放。它们不可能都在使用语句,但我在映像类中使用IDisposable,并保留引用计数以确保。