运行 x86 .NET 应用程序的 Windows 7 x64 将抛出内存不足,除非我执行 GC.Collect
我已经找到了解决方案,但这种行为非常令人担忧,我想在这里询问其他人是否也看到了它。
基本上,在 x64 Windows 7 中运行的固定在 x86 中构建的相同二进制文件(将在下面解释原因)将会泄漏,除非我强制执行 GC.Collect()
解释:
- 应用程序执行大量位图渲染(> 60 每秒)
- 有一个外部 C++ dll(托管 C++)
- 有两个线程(工作线程和 ui)
- 有 UI 刷新(统计)
- 此行为仅发生在本机上,Windows 7 x86 运行良好。
应用程序将增长到超过 1.5G,并最终抛出内存不足异常。 (1) 工作得越快,异常就越快。
对于那些准备拍摄 (2) 导致泄漏的人,我确实测试了将其删除,并且泄漏仍然存在加上,如果我执行 GC.Collect(),内存会得到很好的释放,在我的书中,这是一个.NET 问题。
谢谢。
I have found the solution but the behavior is quite worrying and thought I ask here if anyone else seen it too.
Basically, the same binary which has been pinned to be built in x86 (will explain why below) running in x64 Windows 7 will leak unless I force a GC.Collect()
To explain:
- The application does a lot of bitmap rendering (>60 per/sec)
- There is an external C++ dll (managed C++)
- There are two threads (worker and ui)
- There is UI refreshing (stats)
- This behavior happens only on this machine, Windows 7 x86 runs it fine.
The application will grow to over 1.5G and eventually throw an Out Of Memory exception. The faster (1) works the faster the exception.
For those ready to shoot (2) for causing the leak, I did test removing it and the leak remained plus the memory gets released fine if I do GC.Collect(), which in my books is a .NET issue.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好吧,为了值得,这是我的收获。
我已经看到与您遇到的问题完全相同。它回到了.NET 2.0,但我正在处理大图像,尽管我会处理图像,但内存消耗会增加 - 直到我手动调用
GC.Collect()代码>.
还有什么类似的?主持!我的应用程序是一个非托管 EXE,它将使用
COM
创建一个对象,该对象是暴露给COM
的 .NET 类。这将导致非托管 EXE 托管 CLR。在 Windows X64 上,X32 应用程序将以 WOW(windows on windows)模式加载,这是一种类似的托管,我相信它可以表现出类似的问题。似乎 GC 无法完全了解托管环境中的内存消耗情况。
OK, for what is worth, here is my catch.
I have seen exactly the same issue you are experiencing. It was back in .NET 2.0 but I was working with big images and although I would dispose the images, the memory consumption would go up - until I manually call
GC.Collect()
.What else was similar? Hosting! My application was an unmanaged EXE and that would use
COM
to create a an object which was a .NET class exposed toCOM
. This would cause the unmanaged EXE to host the CLR.On Windows X64, X32 apps will be loaded in WOW (windows on windows) mode which is a similar hosting which I believe can exhibit similar issues. It seems
GC
cannot fully understand the memory consumption when it is in a hosted environment.您是否正确处理位图以及所有其他一次性资源(包括 GDI+ 对象)?
您需要查看您的应用程序才能找到问题 - 显然 1.5GB 对于 32 位应用程序来说是过多的。事实上,您在具有不同操作系统的不同计算机上获得不同的行为并不意味着您应该责怪操作系统。
Are you properly disposing your bitmaps - and all other disposable resources including GDI+ objects?
You need to look at your application to find the problem - clearly 1.5GB is excessive for a 32-bit app. The fact that you are getting different behaviour on different machines with different OS doesn't mean you should blame the OS.
您可以尝试不要过多依赖垃圾收集器。如果您重写绘制代码以清理未使用的资源,您可能不会遇到所描述的情况。
Image.Dispose()
You could try not to rely on the garbage collector as much. If you rewrite your draw code to clean up unused resources, you probably won't run into the scenario described.
Image.Dispose()
当您停止使用位图时,您必须对其进行 .Dispose() 处理。
即使您没有显式调用 .Dispose(),GC 最终也会收集这些内存(当它运行终结器时) - 但 GC 并不是过度分配内存的灵丹妙药,如果您做得更快,那么 GC 就可以使用 GC 无法直接控制的资源(非托管资源正是如此)来收集它们 - 那么 GC 机制就无法帮助您。
通过调用 GC.Collect(0),您将强制 GC 处理对象树并调用所有终结器,如果您不调用它,那么 GC 会在它认为时间到的时候运行,到那时就为时已晚了(由于高分配率)。
You have to .Dispose() of your bitmaps when you stop using them.
The GC will eventually collect this memory (when it runs the finalizer) even if you don't explicitly call .Dispose() - but the GC is not a magic cure for over-allocating memory, if you do it faster then the GC can collect them, using resources the GC cant control directly (unmanaged resources are exactly that) - then the GC mechanism can't help you.
By calling GC.Collect(0) you are forcing the GC to process the object tree and call all the finalizers, if you don't call it then the GC runs when it thinks it's time, and by then it's too late (due to the high allocation rate).