我们测试了在特定计算机上遭受OutOfMemoryExceptions的NUnit测试。
经过调查,它似乎不是内存问题,而是Handle问题(我们分配了太多的Bitmap对象而没有释放它们)。
问题是,这在特定机器上运行完美,而在另一台机器上出现此错误则失败。
我知道最好的解决方案是清理代码以处理任何Bitmap对象,但我有兴趣知道为什么这两台机器在执行相同代码时的行为不同?
答案 0 :(得分:1)
阅读本文: http://blogs.technet.com/b/markrussinovich/archive/2010/02/24/3315174.aspx
您将找到一个表格,列出了各种版本的Windows与GDI堆之间的差异。简答:XP = 3Mb限制,Win7R2x64 = 20Mb限制。免费RAM并不重要,这些都是硬限制。
答案 1 :(得分:1)
这不太可能,Windows允许你泄漏10,000个句柄,然后它会对你的程序行为方式感到不安,并拒绝让你分配更多。到那时,你已经为位图中的像素数据消耗了大量的虚拟内存空间。存储在非托管内存中的垃圾收集器并不知道它。除非您调用Dispose()或垃圾收集器通过运行终结器来处理它,否则VM空间不会被释放。
GC通常不会完成任务,Bitmap类是一个非常小的对象,不足以自行触发GC。您必须分配大约60,000个来触发GC。你永远不会到达那里,除非位图非常小,否则你将首先耗尽虚拟机空间,接下来处理。调用Dispose()是可选的,但由于终结器无法及时完成工作,因此停止对位图是可选的。
RAM的数量在这方面没有任何作用,.NET程序总是会因为它无法在VM地址空间中找到一个足以满足所请求大小的漏洞而受到轰炸。也是位图的一个问题,它们往往需要大洞。它只需要一个DLL在一个尴尬的基地址加载,将一个漂亮的大洞切成两个。否则,一个容易解决的问题,只需将程序的目标平台设置为AnyCPU即可。测试程序具有该配置值。在Win7机器上运行。但是,当然,这不是跳过Dispose()调用的正当理由。