2016-01-28 18 views
14

多くのSO回答とthis widely cited blog postによれば、「32ビット優先」オプションを選択した「任意のCPU」用に構築された.NET 4.5アプリケーションは、32ビットと64ビットの両方のシステムで32ビットプロセスとして実行されます.NET 4.0以前とは異なります)。 つまり、「32ビット優先」を選択したx86およびAnyCPUは同等です(ARM上で実行できるかどうかは無視されます)。「すべてのCPU(32ビット優先)」は、.NET 4.5よりx86より多くのメモリを割り当てることができるのはなぜですか?

しかし私のテストでは、64ビットシステムでは、「AnyCPUが32ビットのアプリケーションを好む」アプリケーション(32ビットで動作することを確認しています)がx86よりも多くのメモリを割り当てることができます。私はOutOfMemoryExceptionに当たるまで十分なRAMを備えた64ビットシステムで実行するまで、ループ内に10MBのバイト配列を割り当てる(もちろん参照を保持する).NET 4.5のC#コンソールアプリケーションを書いた。 x86として構築された場合、約1.2GBが割り当てられます。 「すべてのCPU(32ビット優先)」として構築されたコードは、最大1.5GBです。

なぜ違いがありますか?

答えて

13

Visual Studio 2015では、 'AnyCPU(prefer 32-bit)'としてビルドすると、実行可能ファイルのIMAGE_FILE_LARGE_ADDRESS_AWAREビットが設定されます(editbin /LARGEADDRESSAWAREを実行するのと同じです)。これはdumpbin /HEADERSで確認でき、「アプリケーションは大きな(> 2GB)アドレスを処理できます」という行を探しています。

これはVisual Studio 2013には当てはまりません。変更はapparently undocumentedです。

これは理論上、CLRに2GBを追加する必要があります。割り当て可能なメモリが約300MBだけ上がる理由は分かりません。

+1

10MBのオブジェクトを配列またはリストに割り当てると仮定すると、おそらく* that *配列が壊れている可能性があります。 http://bhrnjica.net/2012/07/22/with-net-4-5-10-years-memory-limit-of-2-gb-is-over/ 'gcAllowVeryLargeObjects'を設定して試してみてください。私の推測では、内部配列のサイズを変更し、 "OOM"にリサイズする 'List'トリガーです。 –

+0

@ChrisMarisic各反復で新しい10MBのバイト配列を作成し、Listに*参照*を追加しますガベージコレクション)。したがって、リスト自体は小さく、わずか数百の参照です。 –

関連する問題