OK、はっきりさせておくと、タスク マネージャーはプログラムのメモリ消費量を監視するのに適した方法ではないことは理解しています。空気を澄ませた今…
私はしばらくの間、SciTech の .Net メモリ プロファイラーを使用してきましたが、ほとんどの場合、私たちのアプリの .Net 3.5 バージョンのみを使用していました。通常、私はオペレーションを実行し、ベースライン スナップショットを収集し、オペレーションを再度実行して比較スナップショットを収集し、そこからリークを攻撃します。一般に、タスク マネージャーはメモリの上昇と下降を模倣します (精度の範囲内で、一定の期間内で)。
私たちの .net 4.0 アプリでは、特定の一連の操作 (操作 A と呼びます) を実行したときに、テスト部門がメモリを報告しました。プロファイラー内で、ライブ バイトのかなりの変化が見られます (通常はリークを示します)。すぐに別のスナップショットを収集すると、(最初の比較スナップショットを収集するのにどれだけ待ったかに関係なく) メモリが再利用されます。ファイナライザーがスタックしている可能性があると考えたので、次の呼び出しを手動で挿入しました。
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
これを行うと、プロファイラーに最初のリークは表示されませんが、タスク マネージャーのワーキング セットは依然として途方もなく高いままです (操作 A には画像の読み込みが含まれます)。この問題はファイナライザーのスタックである可能性があると思いました (そして、プロファイラーがスナップショットを収集するときに SciTech がブードゥーの魔法を実行できたのではないかと考えました)。ファイナライザーが動かなくなっていました。アプリを何時間も放置しただけでは、ワーキング セットのメモリが減少することはありません。ただし、他の操作を実行すると、ランダムなポイントでメモリが大幅に低下します。
私の質問 CLR 4.0 で GC が大幅に変更されたことは知っていますが、OS が割り当てられたメモリを認識する方法に影響はありましたか? 私のコンピューターには 12 GB の RAM が搭載されているため、アプリを実行してメモリ使用量を増やすと、まだ TONS の空き容量があるので、既に割り当てられているものを減らすことは気にしないという仮説を立てています (タスク マネージャーに示されているように)。 )、メモリが「収集」された場合でも。これと同じ操作を 1GB の RAM を搭載したマシンで実行すると、メモリ不足の例外が発生することはありません。これは、実際にメモリ リークが発生していないことを示しています (これはプロファイラーも示唆しています)。
私がタスク マネージャーの表示を気にする唯一の理由は、顧客がメモリ使用量を監視する方法だからです。これに影響を与える GC の変更がある場合は、私たちのせいではなく、Microsoft のせいだというドキュメントを表示できるようにしたいだけです :)
十分な注意を払って、答えを求めて他の SO スレッドを多数検索しましたが、見つけたのは、世代別クリーンアップの同時実行性と、その他の無関係ではあるが有用な事実に関する記事だけです。