2012-11-22 18 views
12

は、そのままで、私はだろうが、とにかくコードを書き換えるための機会を与えられました。List <string>でOutOfMemoryExceptionが発生しました - これが限界ですか、何か不足していますか?</p> <pre><code>List<string> foobar; </code></pre> <p>をその後、我々はfoobarのに文字列の束を追加します:

count = 16777216で、メモリ不足の上限に達しました。

私の理解は、各文字列が異なるサイズであるということです。実際にデータ(私のデータではない)を見ると、ほとんどが2文字または3文字です。 - ちょうど 億2上

リストの現在 実装に格納することができる要素の最大数は、理論的には、Int32.MaxValueをある:

what is the max limit of data into list in c#?は最大限界があることを示しています。しかし

:2GB 最大オブジェクトサイズの制限がありますCLRの現在のMicrosoftの実装では

。 (これは、他の実装は、 は、たとえばモノのために、この制限を持っていない可能性があります。)私の例では

、私は持っているが、何を、1600万結果は数バイトを*?タスクマネージャーはギグが使用されていることを示していますが、私は8ギガのRAMを持っています。

16777216(2^24)はかなり限定的だと思われます。疑いの余地はありますが、どこにもドキュメンテーションがありません。これをバックアップしてください。

ご協力いただければ幸いです。


いくつかのコード:

List<string> returnList = new List<string>(); 
SqlDataReader dr; // executes a read on a database, have removed that part as that bit works fine 

    if (dr.HasRows) 
    { 
     while (dr.Read()) 
     { 
      returnList.Add(dr.GetString(0).Trim()); 
     } 
    } 

簡略化した形だが、私は今、OOM例外のためにいくつかのtry/catchを持っているが、これは私の悲しみを与えている実際のコードです。

+0

あなたのコードを表示できますか? –

+0

ヒープサイズはRAMサイズと異なり、RAMの一部はヒープとして使用され、オブジェクトの格納に使用されます。 http://stackoverflow.com/questions/2325370/c-sharp-increase-heap-size-is-it-posable – CjCoax

+0

@JonSkeet - 一部のスニペットで更新されました。他に必要なものがあれば教えてください。 –

答えて

7

64ビット環境で非常に大きなリストを使用する場合は、アプリケーション構成で大きなオブジェクトを有効にする必要があります。

http://msdn.microsoft.com/en-us/library/hh285054.aspx

OOMが原因私は彼らの境界に到達するたびにあると考えているリストは、/のArrayListのメモリを割り当てる方法に可能性があり、彼らはサイズで倍増しようとします。リストは2^24から倍にすることはできません。理論的には、事前にサイズを指定してリストサイズを最大化することができます。 (つまり、2GB)

+0

これは私のためにそれをした修正でした!ありがとう:) –

1

ここで私が正確に行ったことを投稿しました。 再びステップは:ストアドプロシージャ

  • を使用して、データの各繰り返しクエリ部に

    1. は彼らに次の部分

      List<string> returnList; 
      int index = 0; 
      SqlCommand cmd = new SqlCommand("ExampleStoredProc", conn); 
      cmd.CommandType = CommandType.StoredProcedure; 
      while (true) 
      { 
          cmd.Parameters.Add(
           new SqlParameter("@index", index)); 
          SqlDataReader dr = cmd.ExecuteReader(); 
          if (dr.HasRows) 
          { 
           returnList = new List<string>(); 
           returnList.Add(dr.GetString(0).Trim()); 
           //transfer data here 
          } 
          else 
          { 
           break; 
          } 
          index++; 
      } 
      

    とストアドプロシージャへ

  • 移動を転送します次のようなものにしてください:

    CREATE PROCEDURE ExampleStoredProc 
        @index INT 
    AS 
    BEGIN 
        SELECT * 
        FROM veryBigTable 
        WHERE Id >= (@index *1000) AND Id < ((@index + 1) * 1000) 
    END 
    GO 
    

    あなたが持っているレコードの数にかかわらず、私は確かにあなたが持っているより多くのデータは、完了するまでかかるでしょうに関係なく動作します。

  • 1

    正しいリストサイズを手動で設定すると2^24よりも小さくなっても、それはおそらく適切なトラックにあります。 1600万人に達する代わりに、リストのサイズを2倍にしようとすると、リストを実際に大きくして、先にメモリを使い果たしてしまいます。

    これは、丸数字を取得していた理由を説明しています.2^24に達した後、サイズが大きくなりすぎてメモリが多すぎます。

    リストの実装ではなく、自然なオブジェクトサイズ制限のようなものです。

    関連する問題