LOH (ラージオブジェクトヒープ) でフラグメンテーションが起こる !?

元ネタはこちら

 

CLR のガベージコレクタはメモリを G0、G1、G2 (G は generation の G)、LOH (ラージオブジェクトヒープ) 4つの領域に分けて管理する。G0、G1、G2は 85KB 以下のオブジェクト用、LOH は 85KB よりも大きいオブジェクト用という位置づけである。この LOH がある条件を満たすとフラグメンテーションを起こし、多くのメモリが空いているのに使えない状態になってしまう。

 

CLR が LOH に対してガベージコレクションを欠ける際、参照されていないオブジェクトのメモリ領域を開放するだけで、コンパクション (空いたメモリ領域を詰める処理) を行わない。大きなオブジェクトを移動するのはコストがかかるため、あえてしうないように実装しているらしい。また、CLR は新しいオブジェクトのメモリ領域を確保する際、開き領域を探す手間を軽減するため、前回確保した領域のすぐ後に確保しようとする。

CLR がこのような挙動をするため、寿命が長い大きめ (ぎりぎり LOH に入る程度) のオブジェクトと寿命の短い巨大 (数 MB とかそれ以上) オブジェクトを交互に生成し、かつ巨大オブジェクトのサイズが少しずつ大きくなるような場合に、下の図のように大量のフラグメンテーションが発生してしまう。

問題となるメモリ確保の挙動

こんな状況に陥るのはまれだが、障害解析のための知識の1つとして LOH では大量のフラグメンテーションが起こる可能性がある、ということを頭に入れておくとよいだろう。

Comments

Popular posts from this blog

TFS: 別PCでのチェックアウトを取り消す

WPF の RichTextBox に文字列を設定する&取り出す

WPFアプリにアニメーションGIFを表示させる