低断片化ヒープ(Low Fragmentation Heap)

LFH(Low Fragmentation Heap)は、メモリの断面化を低減させるための仕組み(*)なわけですが
この仕組みを使うためには、意図的に API を呼び出すか、gflags で ON にするかの方法しか
ありませんでした。
しかしながら、Windows Server 2008/Vista ではデフォルト ON になっていますので
わざわざ、有効にする必要はありません。 (情報を提供してくれた MS の S さんありがとう)

Windows Server 2008/Vista では LFH がデフォルト ON になっているため、プログラムの
メモリ測定(Private Bytes)を行う場合には注意が必要です。
LFH が有効になっている場合にはヒープの断片化を抑制する働きによって、プログラム上の
メモリ獲得と解放のタイミングと、実際のプロセス内のメモリ獲得と解放のタイミングとにズレが生じます。
この間、プログラム上から解放したつもりのメモリ領域は、未使用である(再利用可能である)と
マークされるのですが、実際には解放されずに残っています。
この挙動により、表面上、Private Bytes の増減傾向に違いが生じ、短いスパンでモニタリングすると、
あたかもメモリリークしているかのように見えてしまう場合があります。

(*) LFH について

プログラムには、最低一つのヒープメモリが存在します。ヒープメモリはプロセスの起動時に生成され
プロセスの終了時に破棄されます。
ヒープメモリに対して、必要なメモリの確保/解放を繰り返すと、メモリは断片化してしまい
利用効率の低下や場合によってはメモリ量があるにも関わらず、要求サイズの確保に失敗してしまうことがあります。
この現象を低減するために、OS は LFH という仕組みを提供しています。
LFH は、事前に大きいものから小さいものまで各アロケーションサイズ用のメモリブロックを用意しておき、
プログラムが要求するアロケーションサイズに合わせて特定サイズのバケットを割り当てることで、
メモリの断片化を低減させる仕組みです。

LFH を有効にするには、HeapSetInformation() を使います。
使い方は、こんな感じです。

ULONG ulEnableLFH = 2;
if (HeapSetInformation(GetProcessHeap(),
                       HeapCompatibilityInformation,
                       &ulEnableLFH,
                       sizeof(ulEnableLFH)))
{
    printf("Success!\n");
}
else
{
    printf("Failure (%d)\n", GetLastError());
}

ただ、Windows Server 2008/Vista ではデフォルト ON になっていますので
意図的に呼び出す必要はありません。Windows XP や Windows Server 2003 の場合に使ってみてください。
一番有効なのは、プライベートヒープや CRT ヒープに対してかな。