web-dev-qa-db-ja.com

64ビットプロセスのプロセスメモリ制限

私は現在、大量のメモリを必要とする32ビットの.Netアプリケーション(x86 Windows上)を持っています。最近、System.OutOfMemoryExceptionをスローし始めました。

そのため、64ビットプロセスとしてx64プラットフォームに移行することを計画しています。したがって、これはメモリ不足の例外に役立ちます。私はMSDNからこの記事を読んでいました Windowsのメモリ制限

だから、私の質問は、64ビットの.Netアプリケーションをコンパイルする場合、デフォルトとしてIMAGE_FILE_LARGE_ADDRESS_AWAREが設定されますか(記事が示唆しているように)?つまり、8GBのユーザーモード仮想アドレス空間を利用できますか?

17
SysAdmin

X64プロセスの最大メモリ制限は8TBですが、物理メモリの量とシステムのページファイルサイズに依存するため、実際の制限ははるかに少なくなります。詳細については、 この投稿 を参照してください。

IMAGE_FILE_LARGE_ADDRESS_AWAREは、x64 OS(または/ 3GBディレクティブを使用するx86OS)で実行されているx86プロセスに影響します。 x64アプリケーションは、ラージアドレス対応フラグを設定する必要がなく、システムで使用可能なすべての仮想メモリを使用できます。

12
Jeff Cyr

IMAGE_FILE_LARGE_ADDRESS_AWAREは、32ビットプロセスにのみ関連します。その理由は、32ビットWindowsのアドレス空間が2つに分割されているためです。カーネル空間用に2 GB、ユーザー空間用に2GBです。 2 GBをアドレス指定するには、31ビットが必要です。つまり32ビットアプリケーションのポインタは、アドレス指定のために最後のビットを必要としません。

一部のアプリケーションは、カスタム目的でこの余分なビットを使用している可能性があるため、Windowsメモリマネージャーが突然実際の32ビットアドレスを渡した場合、それを処理できません。 IMAGE_FILE_LARGE_ADDRESS_AWAREフラグを有効にすることにより、アプリケーションは基本的に、32ビットのアドレス可能なスペース全体を処理できることをOSに通知します。

32ビットWindowsでIMAGE_FILE_LARGE_ADDRESS_AWAREアプリケーションを実行すると、3GBにアクセスできます。同じ32ビットアプリケーションを64ビットWindowsで実行すると、プロセスは実際には4GBのアドレス空間全体を取得します。

64ビットWindowsで64ビットアプリケーションを実行する場合、ユーザーアドレス空間は8 TB(カーネルアドレス空間用に別の8 TB))です。 AnyCPUに設定されたNETアプリケーションは、x64では自動的に64ビットアプリケーションになるため、追加のメモリをアドレス指定するために何もする必要はありません。

ただし、CLRは単一のオブジェクトに2 GBの制限を課すため、アプリケーションが大量のメモリを使用する可能性がある一方で、たとえば2 TB配列を作成することはできません。詳細この質問の情報: CLR4.0では単一オブジェクトのサイズはまだ2GBに制限されていますか?

13
Brian Rasmussen

実際、その記事には、8 [〜#〜] tb [〜#〜]の仮想アドレス空間にアクセスできると記載されています(もちろん、これは真実です)。

6
Andrew Hare

実際、x64 OSでは、アプリケーションがAnyCPU用にコンパイルされている場合、特別なことをする必要はありません。 JITは、実行時にx64イメージを作成するか、32ビットシステムで実行するとx86イメージを作成します。

6
Josh

64ビットに移行すると、OutOfMemoryExceptionsを確実に削減できますが、64ビットマシンでも表示されるのは時間の問題であるため、システムアーキテクチャとコーディングメカニズムに焦点を当ててこれらを回避することをお勧めします。
64ビットマシンに移行するもう1つの利点は、仮想アドレス空間が8 TBであるため、.NETのガベージコレクションが頻繁に行われないことです。これにより、アプリケーションのパフォーマンスが向上します。プログラムで使用可能な仮想スペース。

5
Bharath K