4

非常に大きな DataTable オブジェクト、非常に大きな配列などを含むアプリケーションがあります。

現在、メモリ使用量は 2GB 未満です。

アプリケーションが 32 ビット システムで 1GB サイズの 4 つの配列を生成するとどうなりますか?

クラッシュしますか?

CLR の 2GB のオブジェクト サイズ制限については知っていますが、多くの大きなオブジェクトについてはどうでしょうか。

私はそれをテストしようとしましたが、いくつかの大きな配列を宣言しましたが、それらが空の場合、RAM を使用していないようです。私はそれらを埋めようとはしませんでした。ここで質問することにしました。

4

5 に答える 5

6

マネージド アプリケーションを含む 64 ビット アプリケーションは、大容量メモリにアクセスできます。

32 ビット アプリケーションには、最大 4GB の仮想アドレス空間があります。実際には、デフォルトで 2GB を取得します。/LARGEADRESSAWAREアプリケーションは、boot.ini の /3gb で 3GB、または WoW64 で実行している場合は 4GB を取得できます。

マネージ アプリケーションは、x64 であっても、2GB を超える単一のオブジェクトを割り当てることはできません。配列を含む。

しかし、自由に利用できる VA の量に関係なく、+2GB のDataTableオブジェクトを操作してもうまくいきません。大量のデータを高速に処理および操作でき、インテリジェントなページングが可能なストレージ エンジンを使用します。RedisCassandra、または従来の RDBMS でさえ、この仕事により適しています。

データをメモリ内で直接操作する場合でも、よりスマートな形式が必要ですDataTable

于 2013-04-25T12:44:43.940 に答える
4

すべての 32 ビット アプリケーションは、2 GB のメモリに制限されています*。したがって、RAM をどのように分割しても、2GB で不足します。

さらに必要な場合は、64 ビット システムで実行し、64 ビット用にコンパイルする必要があります。

  • LARGEADDRESSAWARE 32 ビット アプリケーションを使用すると、最大 3GB のメモリを使用できます。コメントでこれを思い出させてくれた Marc Gravell に感謝します。
于 2013-04-25T12:39:18.693 に答える
1

アドレスできる (または持っている) よりも多くの RAM を使用すると、System.OutOfMemoryException例外が発生します。このコードを試してください:

        List<byte[]> foo = new List<byte[]>();
        for (int i = 0; i < 10000; ++i )
            foo.Add(new byte[1024*1024*1024]);
于 2013-04-25T12:41:02.890 に答える
1

はい、クラッシュします。これは私が試したサンプルコードです:

class Program
{
    static byte[] arr = new byte[1024 * 1024 * 1024];
    static byte[] arr2 = new byte[1024 * 1024 * 1024];
    static byte[] arr3 = new byte[1024 * 1024 * 1024];
    static byte[] arr4 = new byte[1024 * 1024 * 1024];
    static void Main(string[] args)
    {            
        Console.ReadKey();
    }
}

これはかなり原始的なテスト プログラムです。一度に全量のデータに確実に到達できる場合を除き、GC によってすでに部分的に再利用されている可能性があるため、クラッシュすることはありません。

localにすることもできます。ただし、 (コードの最適化を使用して)リリース ビルドを作成すると、未使用の配列 (または通常は変数) が最適化されて削除される可能性があるため、次のビットはチャームのように機能します。

static void Main(string[] args)
{
    byte[] arr = new byte[1024 * 1024 * 1024];
    byte[] arr2 = new byte[1024 * 1024 * 1024];
    byte[] arr3 = new byte[1024 * 1024 * 1024];
    byte[] arr4 = new byte[1024 * 1024 * 1024];
    Console.ReadKey();
}

デバッグ ビルド(コードの最適化なし) では、上記のビットもクラッシュしOutOfMemoryExceptionます。

もちろん、対照的なフィールドをそのままにしておくことはできません。したがって、最初のサンプルは、コードがコンパイラによって最適化されているかどうかに関係なくクラッシュします。

于 2013-04-25T12:42:22.340 に答える
0

さまざまなオペレーティング システムの物理メモリの制限については、この記事「Memory Limits for Windows Releases」を参照してください。

ただし、32 ビットとして実行される .NET アプリケーションの制限を 2GB から最大 3GB に増やすことは可能です。そのためにはeditbin /LARGEADDRESSAWARE、実行可能ファイルで実行する必要があります。詳細については、次を参照してください。

于 2013-04-25T12:49:54.003 に答える