並列で最大 300 個のジョブを処理する必要があるジョブ プロセッサがあります (ジョブは完了するまでに最大 5 分かかる場合がありますが、通常はネットワークにバインドされています)。
私が抱えている問題は、仕事が特定の種類の塊になる傾向があるということです. 簡単にするために、 から までの 6 つのジョブ タイプがあるとJobA
しJobF
ます。
JobA
-JobE
ネットワークにバインドされており、システムにまったく負担をかけずに 300 を一緒に実行することができます (実際、テストで 1,500 以上を並べて実行することができました)。JobF
(新しいジョブ タイプ) もネットワークにバインドされていますが、かなりの量のメモリが必要であり、実際には GDI 機能を使用します。
すべての GDI オブジェクトをusing
s で慎重に破棄していることを確認しており、プロファイラーによると、何もリークしていません。単純に、300JobF
を並列で実行すると、.NET が提供するよりも多くのメモリが使用されるということです。
これに対処するベストプラクティスの方法は何ですか? 私が最初に考えたのは、メモリのオーバーヘッドがどれくらいあるかを判断し、制限に近づくにつれて新しいジョブの生成を抑制することでした (少なくともJobF
ジョブ)。フレームワークがメモリの観点から私に割り当てようとしているものを確実に判断する方法が見つからないため、これを達成できませんでした。また、少し不安定に見えるジョブで使用される最大メモリを推測する必要があります。
私の次の計画は、OOM を取得した場合は単純に調整し、失敗したジョブを再スケジュールすることでした。残念ながら、OOM は問題のあるジョブ内だけでなく、どこでも発生する可能性があります。実際、最も一般的な場所は、ジョブを管理するメインのワーカー スレッドです。現状では、これによりプロセスが正常にシャットダウンし (可能であれば)、再起動して回復を試みます。これは機能しますが、厄介で時間とリソースの浪費です。その特定のジョブをリサイクルするよりもはるかに悪いことです。
この状況を処理する標準的な方法はありますか (メモリを追加することはオプションであり、実行されますが、アプリケーションは爆撃だけでなく、この状況を適切に処理する必要があります)。