2011-06-24 7 views
9

ヒープフラグメンテーションの仕組みを理解しようとしています。次の出力は私に何を伝えますか?管理されたヒープフラグメンテーション

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

私は合計で53304764バイトの「空きオブジェクト」を243010持っています。以前はオブジェクトを含んでいたが、今ではガラベージコレクションされているヒープ内の "フリーオブジェクト"のスペースですか?

断片化されたヒープを強制的にクリーンアップする方法はありますか。

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

答えて

6

ヒープの構成方法によって異なります。あなたは、Gen 0,1,2のどのくらいのメモリが割り当てられているか、使用されているメモリの総量と比較してどれくらいの空きメモリがあるかを調べる必要があります。 500 MBの管理されたヒープが使用されていて、50 MBが空きであれば、かなりうまくいきます。多くのWPFコントロールを作成してリリースするなどのメモリ集中型の操作を行う場合は、短時間に多くのメモリが必要ですが、割り当てられたメモリはOSに戻されません。 GCは割り当てパターンを認識しようとしますが、現在のヒープサイズは物理メモリが不足するまで大きすぎますが、メモリフットプリントは高く保ちます。

.NET 3.5にはpsscor2を使用するほうがはるかに簡単ですが、ListNearObjのようないくつかのクールなコマンドがあり、どのオブジェクトがあなたのメモリホール(固定されたオブジェクト? psscor2のコマンドを使用すると、ヒープで実際に何が起こっているかを知るチャンスがはるかに得られます。ほとんどのコマンドは、.NET 4のSOS.dllでも利用できます。

元の質問に答えるには:はい無料のオブジェクトは、GCセグメンテーションで最後に割り当てられたオブジェクトの後に単に空きメモリブロックである管理されたヒープ上のギャップです。 DumpHeapを実行すると、GCセグメントの開始アドレスを使用して、管理されたヒープセグメントに割り当てられたオブジェクトと、GC収集オブジェクトである空きオブジェクトが表示されます。

このメモリホールは通常Gen2で発生します。フリーオブジェクトの前後にあるオブジェクトアドレスは、潜在的に固定されたオブジェクトがホールの周りにあるかどうかを示します。これから、あなたはあなたの割り当て履歴を決定し、必要に応じてそれを最適化できるはずです。 あなたはGCヒープのセグメントをダンプすることができます!DumpHeap 02aa1000 03836a30で

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. で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 
    .... 

既にGCedされていたオブジェクトであった空きメモリブロックが見つかりました。周囲のオブジェクトをダンプすることができます(出力はソートされたアドレスに分類されます)、それらが固定されているか他の異常な特性を持っているかどうかを調べることができます。

+0

ヒープの断片化が発生する可能性があります(そして最終的にはOutOfMemoryExceptionが発生します)** **固定されたオブジェクトはありませんか?私はGCが断片化されたヒープを掃除していることを理解しています。固定されたオブジェクトを使用しないと、新しいメモリ要求があったときにGCがヒープをクリーンアップできない可能性がありますか?固定されたオブジェクトを除いて、新しい割り当てを行う必要があるときに、(時間内に)クリーンアップできない断片化されたヒープが発生する可能性がありますか? – bitbonk

+0

割り当て率が非常に高い場合、メモリが不足する可能性があります。 GCにきれいにする機会を与えるためにタイトなループで割り当てても、十分ではないかもしれない場合、clrは本当にSleep(50)を組み込んで割り当て要求を抑制します。 –

0

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

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

herehereをご覧ください。 あなたの場合、おそらくピン止めです。 53304764/243010はオブジェクトごとに219.35バイトを作成するため、LOHオブジェクトよりもはるかに低くなります。

+0

私は50MBの空き容量がありますが、それは何ですか*カウント*教えてください? 私は頻繁に小さなオブジェクトをたくさん作成しています(つまり、〜20000 WPFのグリッドを10秒ごとに作成しますが、古いものは参照されなくなり、メモリリークは発生しません)。それを説明することができますか固定されたオブジェクトがより可能性があります。 – bitbonk

関連する問題