2016-10-05 10 views
0

大量のデータを解凍しようとしていますが、次のコードを使用しています。私はエラーを取得する次の繰り返しで、その後罰金と最初の反復が終了:「 「タイプの例外は、 『System.OutOfMemoryExceptionには』がmscorlib.dllで発生したが、ユーザーコードで処理されなかった」あなたはC#関数の呼び出し後のメモリ不足

private static void UnCompressP(byte[] buffToUnCompress, int index, AutoResetEvent eventToTrigger, ref MemoryStream[] memStream) 
{ 
    eventToTrigger.Set(); 
    MemoryStream cmpStream = new MemoryStream(buffToUnCompress); 

    GZipStream unCompZip = new GZipStream(cmpStream, CompressionMode.Decompress, true); 

    byte[] unCompressedBuffer = new byte[buffToUnCompress.Length]; 

    MemoryStream msToAssign = new MemoryStream(); 
    int read = 0; 
    while (0 != (read = unCompZip.Read(unCompressedBuffer, 0, buffToUnCompress.Length))) 
    { 
     msToAssign.Write(unCompressedBuffer, 0, read); 
     msToAssign.Flush(); 
    } 
    memStream[index] = msToAssign; 

    unCompZip.Close(); 
    cmpStream.Close(); 

} 
+0

あまりにも多くのデータをメモリに一度に格納するように思えます。これを避け、代わりに特定の時点でメモリ内の小さな部分のみを保持できるようにするストリームでのみ動作する必要があります。 – Servy

+4

さらに、ソリューションをx86の代わりにターゲットx64に切り替えることもできます。これにより、.NETプロセスのメモリ制限が約2GBになり、使用可能な値になります。 – CShark

+0

私はx64と互換性のないdllファイルを持っています。別のオプションがあります。 –

答えて

0

を何も処理しないでください。すべてのストリームは十分なはずusing { }

とそれを囲むことによって、好ましくは、そのDispose()メソッドまたはを呼び出すことによって配置される必要があるが、あなたは、メモリ上の本当に重大である場合、あなたはあなたのように、戻ってメモリを解放するためにガベージコレクタを待つことができない場合がありますメソッド終了時にガベージコレクタを呼び出す必要があるかもしれません:

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
+1

私はOPが処理していないことに同意します - この場合は助けになるかもしれませんが、 'GC.Collect()'を呼び出すのはとても良い解決策ではないと思います。私が有用と感じる唯一の時間はタイミングコードの実行です。 – Enigmativity

+1

@Enigmativity私は彼が最初にそれを試さなければならないと言いました。 GC.Collect()は時には便利なことがあります。また、メモリの異常に大きな部分が解放された場合に呼び出すのもよい方法です。数MBのオブジェクトを作成する20 MBで動作するアプリケーションを作成しなければならず、GCを呼び出さなければそのことを考えることさえできません。他の唯一のオプションはクラッシュするということです.GCを呼び出すよりもずっと悪いです。 –