膨大な量の地図データを処理する WinForm アプリケーションがあります。操作を高速化するために、頻繁にアクセスされるマップ データを格納するキャッシュ (単純なハッシュ テーブル) があります。キャッシュのサイズを制限している間、タスク マネージャーは増え続けるメモリ消費を示し、最後に OutOfMemoryException を取得します。 奇妙なことに、メモリ プロファイラーと GC.GetTotalMemory の両方と、独自のオブジェクト サイズの計算は同じことを示しています。つまり、キャッシュは制限セットよりも多くのメモリを使用することはありません。キャッシュを無効にすると、システムは正常に動作します。マップ データの処理中に数秒間ピークに達しますが、その後は通常に戻ります。
メモリ プロファイラーは、使用済みスペース (緑色で示されます) がキャッシュ サイズに正確に対応していることを示していますが、予約済みメモリの大部分は使用されていません。
プロファイリング セッション中に、4 つのメモリ スナップショットを取得しました。
- メモリ スナップショット 1: キャッシュあり (最大キャッシュ サイズ 300MB)
- メモリ スナップショット 2: キャッシュ オフ
- メモリ スナップショット 3: 再度キャッシュを有効にする (最大キャッシュ サイズ 300MB)
- メモリ スナップショット 4: 再度キャッシュをオフにする
以下の色分けを見てください。これらの巨大な未使用スペース (青) が取り戻されないのはなぜですか? GC.Collect を呼び出しても違いはありません。