2011-01-14 13 views
2

OutOfMemoryExceptionをスローする前にGC.Collect()を呼び出す方法はありますか?OutOfMemoryExceptionをスローする前にGC.Collectを呼び出す

私はそれが次のコードの流れを行うための方法を探していたとします

Try to Allocate Memory 
On Pass Return 
Call GC.Collect() 
Try to Allocate Memory 
On Fail Throw New OutOfMemoryException() 

私はキャッシュの実装を書いているし、現在、私はそれを解決すべく、現在のメモリの例外に実行していますよ私が使用しています:

If GC.GetTotalMemory(False) >= cache.CacheMemoryLimit + (100 * 1024 * 1024) Then 
    // When Total Memory exceeds CacheMemoryLimit + 100MB 
    GC.Collect() 
End If 
+4

新しいオブジェクトを作成するときにメモリが不足していると、実行時にすでにガベージコレクションが実行されていると思います。 – sisve

+1

@Simon true、通常はOutOfMemoryExceptionがスローされます。ガベージコレクタが静的参照や他の種類のメモリリークを意味するインスタンスのメモリを再利用できない場合があります。クラスローダーは、静的な参照のために特にかなり漏洩します。 – dvhh

答えて

5

をたぶん私はあなたの質問を理解していないんだけど、あなただけのOutOfMemoryExceptionのスローをキャッチし、そこにGC.Collectを呼び出すことは可能ではないでしょうか?あなたがあなたの仕事を終えるまで続けているループの中にtry/catchを投げて、自分自身をきれいにする能力があることを確かめてください。

bool isFinished = false; 
while (isFinished) { 
    try { 
    // do operations in here 
    } catch (OutOfMemoryException oom) { 
    GC.Collect(); 
    } 

    // if you're done... 
    isFinished = true; 
} 

私は選択肢がない限り、VBの代わりにC#疑似を使ってVBで作業しないようにしています。

+0

これは、私の問題を見つけるのに役立ちました。メモリ内のオブジェクトは、アプリケーションがさらにメモリを割り当てようとする前に、まだファイナライズを完了していませんでした。 – Seph

+0

私のテストでは、実際にメモリが不足している(たとえば、配列を割り当てるときに 'ArgumentException'が見られた)ときに、.NETフレームワークが他の例外をスローすることがあります。 Win32エラーはプログラムをただちに終了させます。 – jrh

5

メモリ不足例外の全体的なポイントは、GCへのすべての努力が失敗した後で、メモリが不足していることを知らせることです。キャッシングシステムに真に取り組んでいるのであれば、WeakまたはSoft Referencesを検討することを検討する必要があります。これにより、たとえ参照があっても、メモリが逼迫したときにアイテムを破棄することができます。

キャッシュシステムでは、オブジェクトをルックアップすると1秒後に結果が得られます。メモリは物理的に弱い参照オブジェクトを破棄するのに十分なメモリがあるため、次の秒はNULLになります。この時点で、キャッシュはオブジェクトを再作成してキャッシュに戻し、あたかも最初にオブジェクトを参照したかのように処理を続けます。

5

実際には.NETでは、ガベージコレクションを行い成功したときに、メモリ不足の例外をスローすることができます。これは、Microsoftの.net実装のいくつかの不満の1つです。 1つまたは複数のスレッドで大量のメモリを割り当ててすぐに破棄する単体テストが合格となります。しかし、古い世代の大きな塊が範囲外になると、問題は始まると思います。そのものはすぐに拾われません。

たとえば、一度に1つのディスクから100万個のXmlDocumentを読み取るコードがある場合、いくつかのドキュメントごとにGC.Collect()を実行しない限りOutOfMemory例外が発生する可能性があります。

EDIT:http://social.msdn.microsoft.com/forums/en-US/clr/thread/52a7eb17-ac05-470c-b063-a78427cd4406/

2

GC.Collectはタイミング関連のOutOfMemory例外を修正することができます呼び出します。 上記のJugglistは です。「.NETでは、ガベージコレクションを行い、成功する可能性があるときに、うれしくメモリ不足の例外がスローされます。 私は、非常に時折、OutOfMemory例外を重い負荷の下で投げてしまう高速のソフトリアルタイムビデオ処理システムを持っています。既知の処理デッドバンド(次のカメラトリガの前)にGC.Collectコールを戦略的に配置することで、これらの問題が修正されました。別のオプションとして、必要に応じてオブジェクトを手動で処分することもできましたが、なぜ管理対象環境を使用しているのでしょうか。この問題は、私のアプリがコンパイルされたx86メモリモデルであるという事実によって悪化する可能性がありました。例外的にメモリを大量に使用し、コード内にガベージコレクションを行うのが適切だと思われる場所があると感じたら、それを実行してください。 ここで広く議論されています:What's so wrong about using GC.Collect()?

関連する問題