ERROR_NOT_ENOUGH_MEMORY故障排除

时间:2009-09-21 14:14:26

标签: debugging memory-management out-of-memory

我们的应用程序在具有ERROR_NOT_ENOUGH_MEMORY的某个特定用户的计算机上失败(“没有足够的存储空间可用于处理此命令”)。

该错误显然是在我们正在使用的Delphi VCL框架内的某个地方引发的,所以我不确定哪个Windows API函数负责。

内存有问题吗?GlobalMemoryStatus的调用会提供以下信息:

  • dwTotalPhys - 1063150000(~1 GB)
  • dwAvailPhys - 26735000(~27 MB)
  • dwAvailPage - 1489000000(~1.4 GB)

我觉得奇怪的是,当页面文件中有足够的空间可用时,Windows会让可用的物理内存变得如此之低,但我对Windows的虚拟内存管理知之甚少,不知道这是正常的还是不。是吗?

如果不是内存,那么命中了哪个资源限制?从我在线阅读的内容来看,ERROR_NOT_ENOUGH_MEMORY可能是应用程序遇到任何一个限制的结果(GDI对象,USER对象,句柄等)并不一定是记忆。是否有一个全面的列表,列出了Windows强制执行的限制?有没有办法找出受到限制的限制?我试过谷歌,但我找不到任何系统的概述。

4 个答案:

答案 0 :(得分:4)

检查所有可能性。

可以使用免费的GDIView实用程序监控GDI问题。它是一个文件,用户无需安装程序即可启动。

另外,在相关机器上安装ProcessExplorer

如果您无法访问本机,请要求用户制作应用程序监控状态的屏幕截图。非常喜欢,这会给你一些提示。

答案 1 :(得分:3)

更常见的原因是此错误比您列出的任何错误都是虚拟内存空间碎片。在这种情况下,虽然总空闲存储器是非常合理的,但是空闲空间被分段,其中当前分配了虚拟存储器空间的各个位。因此,如果单个连续块无法满足内存请求,则可能会出现内存不足错误,尽管总空闲时间足够。

答案 2 :(得分:3)

本案的罪魁祸首是CreateCompatibleBitmap。显然,即使您的系统有足够的内存和大量的GDI资源,Windows也可能对可用于设备相关位图的内存强制实施相当严格的系统范围限制(例如,参见this mailing list discussion)。 (这些系统范围的限制显然是因为Windows可能会在视频卡的内存中分配与设备相关的位图。)

解决方案只是使用与设备无关的位图(DIB)(尽管这些可能无法提供相当好的性能)。 This KB article描述了如何为设备选择最佳DIB格式。

资源限制的其他候选人(来自他人的回答和我自己的研究):

  • GDI资源(来自此答案) - 使用GDIView
  • 轻松核对
  • 虚拟内存碎片(来自此答案)
  • 桌面堆 - 请参阅herehere

答案 3 :(得分:0)

我的回答可能有点迟了但是,根据我对同一问题的经验,做了所有测试,一步一步地创建DC,发布它,使用DIBSection代替{{1} },使用泄漏GDI /内存工具等

最后(LOL)我发现:

我正在切换这两个电话的优先级,然后解决了整个问题。

CompatibleBitmap