运行x86 .NET应用程序的Windows 7 x64将丢失内存,除非我执行GC.Collect

时间:2011-04-07 11:13:28

标签: .net windows-7 memory-leaks garbage-collection

我找到了解决方案,但行为非常令人担忧,我想在这里问其他人是否也看过它。

基本上,除非我强制GC.Collect()

,否则在x64 Windows 7中运行的相同二进制文件将被固定在x86中(将在下面解释为什么)

解释:

  1. 应用程序执行大量位图渲染(>每秒60次)
  2. 有一个外部C ++ DLL(托管C ++)
  3. 有两个主题(worker和ui)
  4. 有UI刷新(统计数据)
  5. 此行为仅在此计算机上发生,Windows 7 x86运行正常。
  6. 应用程序将增长到超过1.5G并最终抛出Out Of Memory异常。越快(1)工作越快异常。

    对于那些准备射击(2)造成泄漏的人,我测试将其删除并且泄漏仍然如果我执行GC.Collect(),则内存会被释放。书籍是一个.NET问题。

    谢谢。

4 个答案:

答案 0 :(得分:0)

您是否正确处理了您的位图 - 以及所有其他可支配资源,包括GDI +对象?

using(Bitmap bitmap = ...)
{
    ... do your stuff
}

您需要查看您的应用程序才能找到问题 - 对于32位应用程序来说,1.5GB显然是过多的。您在具有不同操作系统的不同计算机上获得不同行为的事实并不意味着您应该责怪操作系统。

答案 1 :(得分:0)

你可以尽量不要依赖垃圾收集器。如果您重写绘制代码以清理未使用的资源,则可能不会遇到所描述的场景。

Image.Dispose()

  

注意始终在您之前调用Dispose   发布你的最后一个引用   图片。否则,它是资源   使用将不会被释放,直到   垃圾收集器调用Image   对象的Finalize方法。

答案 2 :(得分:0)

当你停止使用它们时,你必须.Dispose()你的位图。 GC最终会收集这个内存(当它运行终结器时),即使你没有显式调用.Dispose() - 但是GC不能过度分配内存,如果你做得更快,那么GC可以收集它们,使用GC cant直接控制的资源(非托管资源就是这样) - 然后GC机制无法帮助你。

通过调用GC.Collect(0),你强制GC处理对象树并调用所有终结器,如果你没有调用它,那么当GC认为是时候GC就会运行,到那时为时已晚(由于分配率高)。

答案 3 :(得分:0)

好的,值得一提的是,这是我的抓地力。

我见过您遇到的完全相同的问题。它回到了.NET 2.0,但我正在使用大图像,虽然我会处理图像,但内存消耗会增加 - 直到我手动调用GC.Collect()

还有什么相似之处?主机!我的应用程序是一个非托管的EXE,它将使用COM创建一个对象,该对象是一个暴露给COM的.NET类。这将导致非托管EXE托管CLR。

在Windows X64上,X32应用程序将加载到 WOW (windows on windows)模式,这是一个类似的托管,我相信可以展示类似的问题。似乎GC无法完全理解托管环境中的内存消耗。