2017-07-25 5 views
2

私は画像でいくつかの操作を行うforeachループを持っています。このコードを50以上の画像で実行すると、OutOfMemoryExceptionが表示されていました。画像インスタンスはそれぞれ15MB以上であるためです。ガベージコレクタがforeachループで遅すぎますか?

var files = Directory.GetFiles(path).ToList(); 

foreach (var file in files) 
{ 
    Image image = new Bitmap(file); 

    //Do some operations 
} 

メインロジックを削除しましたが、これはこのコードにこの問題が残っているためです。 foreachループにGC.Collect();を追加すると、問題はなくなり、例外は発生しません。

私の質問は、Collectメソッドを呼び出さずにガベージコレクタが不要になったイメージをクリーンアップするには時間がかかりすぎるのですか、それとも他に何か不足していますか?

以前はこの問題に気付かなかった。 //Do some operationsの部分が各画像に対して〜1秒必要なので、問題はないと私は考えなかった。私が思ったガベージコレクターのための十分な時間でなければなりません。

+0

がうまくあなたが本当に選択肢がありません。あまりにも遅いのはどういう意味ですか? –

+0

@PaulFは重複していません。 OPは何かを尋ねています –

+0

@YvetteColomb:私はそれが重複しているかのように見えます - OPはビットマップを使用するときにメモリ不足の問題を抱えています - GCはアンマネージメモリを自動的に処理しないためです。与えられた解決策がその質問に答えます。以下のRomanoの答えも見てください。 – PaulF

答えて

7

おそらく、あなたはusingで動作します:

var files = Directory.GetFiles(path).ToList(); 

foreach (var file in files) 
{ 
    using (Image image = new Bitmap(file)) 
    { 
     // do work 
    } 
} 

反復

+0

ありがとう、 'Bitmap'を忘れて、それを廃棄しました;) –

2

が明示的にインスタンスを配置しようとしたことがあり後Bitmapが配置されます。この方法は?

var files = Directory.GetFiles(path).ToList(); 
foreach (var file in files) 
{ 
    Image image = new Bitmap(file); 

    //Do some operations 
    image.Dispose(); 
    //image = null; 
} 

usingブロックでも同じことが実現できます。

1

問題はGCではなく、ビットマップを使用しています。 GCは、最終的にそれらをピックアップしますが、あなたは自分のタイムリーな処分を確保するためにusingブロック内の画像の作成をラップする必要があります:あなたはOutOfMemoryExceptionsを取得している場合

foreach (var file in files) 
{ 
    using (Image image = new Bitmap(file)) { 
     //Do some operations 
    } 
} 
関連する問題