web-dev-qa-db-ja.com

64ビットWindowsで実行しているときに2GBのメモリ制限があるのはなぜですか?

私はDelphiアプリケーションを開発するチームのメンバーです。メモリ要件は膨大です。 500 MBは正常ですが、メモリ不足の例外が発生する場合があります。その場合に割り当てられるメモリは、通常1000〜1700MBです。

もちろん64ビットコンパイラが必要ですが、今は実現しません(発生した場合は、Unicodeに変換する必要がありますが、それは別の話です...)。

私の質問は、64ビット環境で実行しているときにプロセスごとに2GBのメモリ制限があるのはなぜですか。ポインタは32ビットなので、4GBが適切な制限だと思います。 Delphi2007を使用しています。

EDIT:したがって、DelphiでIMAGE_FILE_LARGE_ADDRESS_AWAREフラグを次のように設定した場合:

{$SetPeFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

そして、結果のExeファイルをWindows Server 2003 x64で実行すると、アプリケーションは4 GBをアドレス指定できますか?

  • Boot.iniで/ 3GBスイッチを設定する必要がありますか?
  • これを試しましたが、32ビットのWindows Server 2003で、Windowsリソースが制限されているようです。ログにGDIErrorを伴う「メモリ不足」の例外がさらにありました。しかし、64ビットOSで実行すると、これが消える可能性がありますか?
31

/ LARGEADDRESSAWAREフラグを使用してDelphiアプリケーションをコンパイルすると、64ビットOSで4GB全体をアドレス指定できるようになります。それ以外の場合、WOW32で実行すると、OSは、アプリが32ビットOSと同じ環境を想定していると想定します。つまり、4GBのアドレス空間のうち、2GBがOS専用で、2GBがに割り当てられます。アプリケーション。

32
Thomas

PE実行可能ファイルにLARGEADDRESSAWAREフラグを設定するためのDelphiの構文は次のとおりです。

{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

それを.dprファイルに入れます。

14
user160694

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

各32ビットプロセスのユーザーモード仮想アドレス空間:2 GB

6
Matthew Groves

LARGE_ADDRESS_AWARE PEフラグを含めることにより)上位ビットが設定された32ビットポインターの受信を選択する限り、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;

enter image description here

結論

$ 7FFFFFFFを超えるポインターを処理できることを誓う限り、64ビットWindowsでは2GBの制限はありません。

:すべてのコードはパブリックドメインにリリースされます。帰属は必要ありません。

2
Ian Boyd