定期的に実行され、大量のデータ (テキストのみ) をリモート サーバーからダウンロードするネットワーク アプリケーション (WCF NetTcpBinding) を試しています。アプリケーションは、System.Threading.Timer を使用して Windows サービス内で実行されます。
protected override void OnStart(string[] args)
{
int interval = // get interval from some config file
timer = new Timer(new TimerCallback(x => DoWork()), null, 0, interval);
}
私が観察しているのは、大量のデータがダウンロードされている場合、サービス プロセスが約 300,000 KB のワーキング セット メモリを消費することです (これは、データ量から予想されます)。ただし、操作が完了した後、プロセスは約 300,000 kb に留まります。実行した CLR プロファイラーによると、これはスタック メモリですが、100% 確実ではありません。
X 分間のインターバルの後、サービスがダウンロードの別のバッチを開始すると、プロセスは約 15,000 kb の低いメモリ使用量に戻り、ダウンロードするデータがさらに多くある場合にのみ、すぐに再び立ち上がります。ただし、ダウンロードするデータがほとんどまたはまったくない場合、プロセスは約 300,000 kb でハングし続けます。
この状況で、各間隔が完了した後に GC.Collect を使用するのは理にかなっていますか (各間隔での操作は互いに完全に独立しています)、または GC が独自にこれを行う必要がありますか? GC は、古いバッチから残ったメモリをクリアする前に、処理の新しいバッチにさらに多くのメモリが必要になるまで待機しているように思えます。それ自体はメモリ リークではありませんが、GC は必要以上に長く待機しています。これが仕様によるものなのか、それとも私のコードにこの動作を引き起こしている可能性があるのか 、興味がありますか? また、実際にスタック メモリである場合、GC は実際には関与していないという印象を受けました。ただし、次のコードをテストしたところ、すぐにメモリがクリアされるようです。
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);