32

コレクションが .Net でどれだけ大きくなるかをテストしています。技術的には、どのコレクション オブジェクトも物理メモリのサイズまで大きくなる可能性があります。

次に、Windows 2003 サーバーと Visual Studio 2008 を実行する 16 GB メモリのサーバーで次のコードをテストしました。F# と C# コードの両方をテストし、実行中にタスク マネージャーを確認しました。約 2GB のメモリを増やした後、プログラムがメモリ不足の例外でクラッシュしたことがわかります。プロパティ ページでターゲット プラットフォームを x64 に設定しました。

open System.Collections.Generic

let d = new Dictionary<int, int>()

for i=1 to 1000000000 do
    d.Add(i,i)

C5コレクション ライブラリに対して同じテストを行いました。その結果、C5 のディクショナリがメモリ全体を使い果たす可能性があります。コードは C5 を使用します。

let d = C5.HashDictionary<int, int> ()
for i=1 to 1000000000 do
    d.Add(i,i)

誰でも理由を知っていますか?

4

4 に答える 4

42

Microsoft CLR には、64 ビット バージョンであっても最大オブジェクト サイズの制限が 2GB あります。(この制限が Mono などの他の実装にも存在するかどうかはわかりません。)

この制限は、すべてのオブジェクトの合計サイズではなく、個々のオブジェクトに適用されますつまり、何らかの複合コレクションを使用して回避するのは比較的簡単です。

ここに議論といくつかのサンプルコードがあります...

この制限について言及している公式文書はほとんどないようです。結局のところ、これは現在の CLR の実装の詳細にすぎません。私が知っている唯一の言及は、このページにあります:

64 ビットの Windows オペレーティング システムで 64 ビットのマネージド アプリケーションを実行する場合、作成できるオブジェクトのサイズは 2 ギガバイト (GB) 以下です。

于 2010-09-07T08:54:14.810 に答える
22

4.5 より前のバージョンの .NET では、最大オブジェクト サイズは 2GB です。4.5 以降では、 gcAllowVeryLargeObjectsが有効になっている場合、より大きなオブジェクトを割り当てることができます。の制限stringは影響を受けませんが、リストは配列によって支えられているため、「配列」は「リスト」もカバーする必要があることに注意してください。

于 2012-06-26T06:49:18.960 に答える
11

そして明確にするために、ディクショナリは単一の配列を使用してペアを追加します。いっぱいになるたびに成長します(2倍になりますか?)。5億1,200万個のオブジェクトがある場合、そのサイズは2GByteです(32ビットのオブジェクトポインターを使用し、完全な分散を想定しています)。要素をもう1つ追加すると、ディクショナリは配列サイズを2倍にしようとします。ブーム。

C5 HashDictionaryは線形ハッシュを使用し、おそらくそれぞれが複数(16?)の要素を含むバケットの配列を使用します。後で同じ問題が発生するはずです。

于 2010-10-13T09:34:54.873 に答える