10

ヒープの断片化がどのように機能するかを理解しようとしています。次の出力は何を示していますか?

このヒープは過度に断片化されていますか?

合計 53304764 バイトの 243010 個の「空きオブジェクト」があります。かつてオブジェクトを含んでいたが、現在はガベージ収集されているヒープ内の「空きオブジェクト」スペースはありますか?

断片化されたヒープを強制的にクリーンアップするにはどうすればよいですか?

!dumpheap -type Free -stat
total 243233 objects
Statistics:
      MT    Count    TotalSize Class Name
0017d8b0   243010     53304764      Free
4

2 に答える 2

7

ヒープがどのように編成されているかによって異なります。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されたオブジェクトである空きメモリブロックがあります。周囲のオブジェクトをダンプして(出力はアドレスごとにソートされます)、それらが固定されているか、または他の異常なプロパティを持っているかどうかを確認できます。

于 2011-07-01T21:43:19.050 に答える
0

空き容量として 50MB の RAM があります。これは良くない。

.NET がプロセスから 16 MB のブロックを割り当てると、実際に断片化の問題が発生します。.NET で断片化が発生する理由はたくさんあります。

ここここを見てください。あなたの場合、それはおそらく固定です。53304764 / 243010 では、オブジェクトあたり 219.35 バイトになるため、LOH オブジェクトよりもはるかに低くなります。

于 2011-06-30T14:54:13.327 に答える