ヒープがどのように編成されているかによって異なります。Gen 0,1,2で割り当てられているメモリの量と、使用されているメモリの合計と比較した場合の空きメモリの量を確認する必要があります。500 MBのマネージヒープを使用しているが、50 MBが無料の場合は、かなりうまくいっています。多くのWPFコントロールを作成して解放するなど、メモリを大量に消費する操作を行う場合は、短時間でより多くのメモリが必要になりますが、.NETは、割り当てたメモリをOSに戻しません。GCは割り当てパターンを認識しようとし、マシンの物理メモリが少なくなるまで現在のヒープサイズが大きすぎるにもかかわらず、メモリフットプリントを高く保つ傾向があります。
.NET 3.5用のpsscor2を使用する方がはるかに簡単であることがわかりました。これには、メモリホールの周囲にあるオブジェクト(ピン留めされたオブジェクト?)を見つけることができるListNearObjのようないくつかのクールなコマンドがあります。psscor2のコマンドを使用すると、ヒープで実際に何が起こっているのかを知るチャンスがはるかに高くなります。ほとんどのコマンドは、.NET4のSOS.dllでも使用できます。
元の質問に答えるには:はい、空きオブジェクトは管理対象ヒープ上のギャップであり、GCセグメントで最後に割り当てられたオブジェクトの後の空きメモリブロックになります。または、GCセグメントの開始アドレスを指定して!DumpHeapを実行すると、その管理ヒープセグメントに割り当てられたオブジェクトと、GCで収集されたオブジェクトである空きオブジェクトが表示されます。
このメモリホールは通常、Gen2で発生します。フリーオブジェクトの前後のオブジェクトアドレスは、穴の周りに固定されている可能性のあるオブジェクトを示します。これから、割り当て履歴を決定し、必要に応じて最適化できるはずです。GCヒープのアドレスは次のように見つけることができます
0:021> !EEHeap -gc
Number of GC Heaps: 1
generation 0 starts at 0x101da9cc
generation 1 starts at 0x10061000
generation 2 starts at 0x02aa1000
ephemeral segment allocation context: none
segment begin allocated size
02aa0000 02aa1000** 03836a30 0xd95a30(14244400)
10060000 10061000** 103b8ff4 0x357ff4(3506164)
Large object heap starts at 0x03aa1000
segment begin allocated size
03aa0000 03aa1000 03b096f8 0x686f8(427768)
Total Size: Size: 0x115611c (18178332) bytes.
------------------------------
GC Heap Size: Size: 0x115611c (18178332) bytes.
ここで、02aa1000と10061000にヒープがあることがわかります。!DumpHeap02aa1000 03836a30を使用すると、GCヒープセグメントをダンプできます。
!DumpHeap 02aa1000 03836a30
Address MT Size
...
037b7b88 5b408350 56
037b7bc0 60876d60 32
037b7be0 5b40838c 20
037b7bf4 5b408350 56
037b7c2c 5b408728 20
037b7c40 5fe4506c 16
037b7c50 60876d60 32
037b7c70 5b408728 20
037b7c84 5fe4506c 16
037b7c94 00135de8 519112 Free
0383685c 5b408728 20
03836870 5fe4506c 16
03836880 608c55b4 96
....
そこには、すでにGCされたオブジェクトである空きメモリブロックがあります。周囲のオブジェクトをダンプして(出力はアドレスごとにソートされます)、それらが固定されているか、または他の異常なプロパティを持っているかどうかを確認できます。