代码之家  ›  专栏  ›  技术社区  ›  Josh Kelley

故障排除错误\内存不足

  •  5
  • Josh Kelley  · 技术社区  · 15 年前

    我们的应用程序在一个特定用户的计算机上出现故障 ERROR_NOT_ENOUGH_MEMORY (“存储空间不足,无法处理此命令”)。

    这个错误显然是在我们使用的DelphiVCL框架的某个深层次出现的,所以我不确定是哪个WindowsAPI函数造成的。

    记忆有问题吗? 对…的呼唤 GlobalMemoryStatus 提供以下信息:

    • dwtotalphys-1063150000(~1 GB)
    • 德瓦伊尔菲-26735000(~27MB)
    • dwavailpage-1489000000(约1.4 GB)

    我觉得很奇怪,当分页文件中有这么多可用空间时,Windows会让可用的物理内存变得如此之低,但我对Windows的虚拟内存管理还不太了解,无法知道这是否正常。它是?

    如果不是内存,那么将达到哪个资源限制? 从我在网上看到的, 错误\内存不足 可能是应用程序达到了几个限制(gdi对象、用户对象、句柄等)的结果,不一定是内存。是否有Windows实施的限制的全面列表?有没有办法知道达到了什么限度?我试过谷歌,但找不到任何系统的概述。

    4 回复  |  直到 12 年前
        1
  •  4
  •   RED SOFT ADAIR    15 年前

    检查所有可能性。

    可以使用免费的 GDIView 实用工具。它是一个单独的文件,用户可以在没有安装程序的情况下启动。

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

    如果您没有访问机器的权限,请要求用户对应用程序监视的状态进行屏幕截图。很像Eley,这会给你一些提示。

        2
  •  3
  •   AnthonyWJones    15 年前

    比您列出的任何错误都更常见的原因是虚拟内存空间的碎片。在这种情况下,尽管总的可用内存是相当合理的,但是可用空间是由当前分配的虚拟内存空间的不同位分割的。因此,当一个连续的块不能满足对内存的请求时,尽管总的空闲空间足够,您仍然可以得到一个内存不足错误。

        3
  •  3
  •   Josh Kelley    15 年前

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

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

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

    • GDI资源(来自此答案)-轻松检查 GDIView
    • 虚拟内存碎片(来自此答案)
    • 桌面堆-请参阅 here here
        4
  •  0
  •   andr Gal Mathys    12 年前

    我的答案可能有点晚了,但是,根据我在同一个问题上迟来的经验,做所有的测试,一步一步地进行,创建DC,释放它,使用 DIBSection 而不是 CompatibleBitmap ,使用泄漏GDI/内存工具等。

    最后(lol)我发现:

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

    DeleteDC(hdc);       //do it first (always before deleting objects)
    DeleteObject(obj);