【问题标题】:Why 2 GB memory limit when running in 64 bit Windows?为什么在 64 位 Windows 中运行时有 2 GB 内存限制?
【发布时间】:2011-02-13 23:32:59
【问题描述】:

我是开发 Delphi 应用程序的团队的成员。内存需求很大。 500 MB 是正常的,但在某些情况下它会出现内存不足异常。在这种情况下分配的内存通常在 1000 - 1700 MB 之间。

我们当然想要 64 位编译器,但现在不会发生(如果发生,我们还必须转换为 unicode,但那是另一回事了……)。

我的问题是为什么在 64 位环境中运行时每个进程有 2 GB 的内存限制。指针是 32 位的,所以我认为 4 GB 是正确的限制。 我使用的是 Delphi 2007。

编辑: 因此,如果我在 Delphi 中使用以下方法设置 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志:

{$SetPeFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

然后在 Windows Server 2003 x64 上运行生成的 Exe 文件,那么应用程序可以寻址 4 GB 吗?

  • 我应该在 boot.ini 中设置 /3GB 开关吗?
  • 我们已经尝试过,但在 32 位 Windows Server 2003 上,它似乎限制了 Windows 资源。日志中出现更多带有 GDIError 的“内存不足”异常。但在 64 位操作系统中运行时,这可能会消失吗?

【问题讨论】:

  • boot.ini 中的 3GB 开关仅适用于 32 位 Windows,需要 LARGEADDRESSAWARE 才能正常工作。请注意,它会缩小 Windows 本身在 32 位系统上的可用空间。请参阅此处的示例,blogs.technet.com/markrussinovich/archive/2009/03/26/…,或阅读 Russinovoch 和 Solomon 的优秀 Windwos Internals。

标签: delphi delphi-2007 win64


【解决方案1】:

如果您使用 /LARGEADDRESSAWARE 标志编译 Delphi 应用程序,它将能够在 64 位操作系统上处理全部 4GB。否则,当在 WOW32 中运行时,操作系统假定应用程序期望的环境与它在 32 位操作系统上的环境相同,这意味着在 4GB 的地址空间中,2GB 专用于操作系统,2GB 分配给应用程序。

【讨论】:

  • 这仅在 32 位上有效。 3GB 指针和 4GB 指针之间没有二进制差异,因此任何可以处理 3GB 的应用程序都可以处理 4GB。 /LARGEADDRESSAWARE 适用于 64 位系统上的完整 4GB,无需任何启动修改。唯一需要做 /3GB 是如果你想在 32 位系统中使用更多的地址空间。您链接的文章已经过时了大约十年,并且仅针对 32 位系统。 PAE 是一个完全不同的系统。
  • @Deltics - LARGEADDRESSAWARE 不仅适用于 3GB 这绝对不正确。 msdn.microsoft.com/en-us/library/wz223b1z%28VS.80%29.aspx。这表明应用程序可以处理 2GB 以上的 ANY 地址。如果您想在具有 32 位应用程序的 64 位操作系统上获得完整的 4GB 地址空间并且它可以处理它,那么您可以使用 LARGEADDRESSAWARE 开关,这是绝对正确的。我不知道你为什么认为这是不正确的。
  • 答案具体是syas 64位操作系统,那么问题出在哪里?
  • @Deltics - 此外,您提供的文章的第一段完全支持我所说的关于 4GB 地址空间以及操作系统使用 2GB 和应用程序使用 2GB 的内容。这是 32 位操作系统的默认行为。 /3GB 是一个功能,您可以手动启用它来更改此动态,以便最多可以将 3GB 分配给应用程序如果它是旨在处理额外的寻址。
  • @All:是的,除了以连词开头的第二句话让我感到困惑之外,没有问题。我的错。我删除了冒犯性的评论,不是为了避免脸红,而是为了避免在任何人的脑海中播下怀疑的种子。
【解决方案2】:

Delphi 中在 PE 可执行文件中设置 LARGEADDRESSAWARE 标志的语法是:

{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

将其放入您的 .dpr 文件中。

【讨论】:

    【解决方案3】:

    http://msdn.microsoft.com/en-us/library/aa366778(VS.85).aspx

    每个 32 位进程的用户模式虚拟地址空间:2 GB

    【讨论】:

    • Windows 无法知道 Delphi 对内存地址使用有符号还是无符号算法,因此它必须假定高位不可用,除非您明确声明。
    • @Mark:嗯,这根本不是真的。如上所述,设置启动标志将允许 Delphi 寻址超过 2GB
    • @BlueRaja, "设置启动标志" = "明确声明否则"。
    • @Mark:我的意思是操作系统中的启动标志。它与 Delphi 或有符号算术完全无关(指针算术无论有符号还是无符号都是一样的!)
    【解决方案4】:

    只要您选择接收设置了高位的 32 位指针(通过包含 LARGE_ADDRESS_AWARE PE 标志),就没有 2GB 的限制。

    直接观察

    var
       p: Pointer;
       n: Int64;
    begin
       p := Pointer($D0000000); //Above the 2GB line; and the 3GB line!
    
       p := VirtualAlloc(p, 1024, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
       if p = nil then
          RaiseLastWin32Error;
    
       n := Cardinal(p);
       ShowMessage(IntToHex(n, 16));
    end;
    

    结论

    在 64 位 Windows 上没有 2GB 的限制,只要你发誓你可以处理高于 $7FFFFFFF 的指针。

    注意:任何代码都会发布到公共领域。无需署名。

    【讨论】:

      猜你喜欢
      • 2021-07-16
      • 2012-02-03
      • 2012-01-28
      • 2018-05-03
      • 2020-11-17
      • 2014-05-07
      • 1970-01-01
      • 2016-06-07
      相关资源
      最近更新 更多