运行测试时在特定计算机上的内存不足异常

本文关键字:内存不足 异常 计算机 运行测试 | 更新日期: 2023-09-27 18:33:29

我们有一个针对在特定机器上遭受 OutOfMemoryExceptions 的 NUnit 测试的测试。

经过调查,似乎这不是内存问题,而是句柄问题(我们分配了太多的位图对象而没有释放它们(。

问题是,这在特定机器上完美运行,而在另一台机器上则因此错误而失败。

  1. 故障计算机是装有 Windows7 x64(6 GB 内存(的 Hyper-V VM
  2. 工作机器是物理机器Windows XP(2 GB ram(

我知道最好的解决方案是清理代码以处理任何位图对象,但我有兴趣知道为什么这两台机器在执行相同代码时行为不同?

运行测试时在特定计算机上的内存不足异常

阅读以下内容:http://blogs.technet.com/b/markrussinovich/archive/2010/02/24/3315174.aspx

您将找到不同版本的 Windows 在 GDI 堆方面的差异表。 简短回答:XP = 3Mb 限制,Win7R2x64 = 20Mb 限制。 可用RAM无关紧要,这些都是硬性限制。

这不太可能,Windows 允许您泄漏 10,000 个句柄,以免它对您的程序行为方式产生胡思乱想并拒绝让您分配更多。 到那时,您已经为位图中的像素数据消耗了大量的虚拟内存空间。 存储在非托管内存中,垃圾回收器不知道它。 除非调用 Dispose(( 或垃圾回收器通过运行终结器来处理它,否则不会释放的 VM 空间。

GC 通常不会完成工作,Bitmap 类是一个非常小的对象,不足以自行触发 GC。 您必须分配大约 60,000 个才能触发 GC。 你永远不会到达那里,除非位图非常小,否则你将首先用完 VM 空间,接下来处理。 调用 Dispose(( 是可选的,但对于位图来说不再是可选的,因为终结器无法及时完成工作。

RAM 的数量在这方面没有任何作用,.NET 程序总是轰炸它,无法在 VM 地址空间中找到足够大的漏洞以适应请求的大小。 位图也是一个问题,它们往往需要大孔。 它只需要一个在尴尬的基址加载的DLL就可以将一个漂亮的大洞切成两半。 否则很容易解决的问题,只需将程序的目标平台设置为 AnyCPU。 测试程序具有该配置值。 适用于该 Win7 计算机。 但是,当然,这不是跳过Dispose((调用的正当理由。