2009-05-27 12 views
0

私は、社内のC#プログラムを書いています。これは主に他のAPIに依存するさまざまなファイル形式間のバッチ変換です。現在、UIはコンバージョンを処理するBackgroundWorker(スレッドではない)を生成し、ワーカーがジョブを完了すると空になるリクエストをキューに入れます。キューオブジェクト自体は非常に小さく(作業者に何をすべきかを伝える3つの文字列)、プログラムのメモリフットプリントに大きく寄与しません。私は自分のメモリ管理について非常に厳しい経験をしています(画像を処理し終わった時点で特定のポイントで手作業でガベージコレクションを行います)。しかし、プログラムは一度に約100 MBのメモリを使用する傾向があり、合計CPU時間。私は素朴にスレッディングを実装していたように思えますが、CLRが何らかの魔法を知らない限り、すぐにシステムメモリが使い果たされてしまうようです。マルチスレッドアプリケーションのメモリ不足の防止

スレッドを防ぐための簡単で効率的な方法はありますかシステムはOutOfMemory例外をキャッチし、死んだスレッドをロールバックする以外にメモリが不足することはありません(非常に非効率的ですが、膨大な量のメモリを使用せずに状態を保持する方法はありません)。

+2

私たちは何スレッドを話していますか? UIと1人のワーカーが言及していますが、それは大きな問題ではありません。たくさんのスレッドを産んでいますか? –

+0

私は1つのBackgroundWorkerオブジェクト(スレッドではない)を現在持っています。私はより多くのCPU使用率を許可するが、システムのメモリ不足を防ぐために、さらに追加したいと思います。私が言ったように、1人のワーカーがいるUIには最大100 MBのRAMが必要なので、さらにスレッドを追加することも問題になるかもしれません。バッチジョブは日常的に100ファイルを超えることができます。 – pschorf

答えて

2

ThreadPool.QueueUserWorkItemを使用して変換を開始すると、実行中のスレッドの数に自動的に制限が適用されます。 ThreadPoolはこれを内部的に管理し、プールスレッドが利用可能になるとすぐにキューに入れられた呼び出しを処理します。

0

キューのサイズに制限を設け、送信者がいっぱいになると送信待ちにします。あなたは経験的に正しいキューサイズ制限を見つける必要があります。

0

メモリ不足の例外は扱いにくく、断片化されたメモリが原因で実際​​にメモリが不足している可能性があります。したがって、彼らは追跡するのが難しいかもしれません。

Sweeden(http://blogs.msdn.com/tess/)のMicrosoft製品サポートからのTessには、メモリがこのプロセスで役立つメモリを追跡するための数多くの投稿があります。

あなたのアプリの良いプロフィールも役に立ちます。 JetBrainsはAQTimeと同じように優れています。

0

画像処理アプリケーションでは、100MBのメモリを使用することはあまりありません。

また、OutOfMemory例外が発生すると、プロセス全体が終了しますが、これから回復することはできません。

システムよりも多くのメモリ(またはより正確にはアドレススペース)が必要な場合は、メモリを使用したり、64ビットに切り替えるためにメモリをページングしたり、ページアウトしたりできます。

"重い"メモリユーザーだけがワーカースレッドであることを確認するためにキューサイズを制限することができます。複数のワーカースレッドを持つことができます。メモリ使用量は増加しますが、これは、CPUコアよりもスレッド数が多いこのような集中的な操作では効率が悪いことです。

あなたは「素朴に実装されたスレッド」について語りますが、マルチスレッドには落とし穴がたくさんあります。単純な実装では効率が悪く、バグがたくさんあります。