3

ヒープの断片化により、何ヶ月も連続して実行されることが予想されるサーバー アプリケーションが、メモリ不足であると考えて突然誤動作を開始する可能性があります。

VC++ サーバー アプリケーションでランタイム ヒープの断片化を最小限に抑えるために最善を尽くしたにもかかわらず、それでも断片化が蓄積され、問題が発生すると仮定します。たとえば、毎月または 50 万回のリクエストが処理されるたびに、アプリケーションを自動的に再起動することができます。安全に停止し、新しいヒープで安全に再開できます。ヒープの断片化を回避するために他に何ができますか?

4

4 に答える 4

3

ここと同じ答え: How to detect heap fragmentation in my C++ program?

メモリ割り当てパターンに合わせた独自のメモリ マネージャを作成します。または、1 つ購入します (たとえば、スマート ヒープ)。

断片化はメモリ割り当てパターン/解放パターンに依存するため、より良い答えを出すのは困難です。ただし、固定サイズのアロケーターを調べるか、スマート ヒープ ページで割り当てを処理する方法を調べることができます。このトピックに関する多くの論文もあります。たとえば、www.memorymanagement.orgを試してください。

または、 FastMM4を見ることもできます。これはオープン ソースですが、Pascal/Delphi で

プログラミングのテクニックもあります。最も注目すべきは、Object Poolです。この場合、オブジェクトは再利用され、解放されないため、断片化はありません。しかし、固定サイズのアロケーターは、オブジェクト プールよりもパフォーマンスが優れていると思います。この方法で使用されるオブジェクト プールは、「貧しい人々」の固定サイズ アロケータにすぎません。

于 2009-10-20T06:34:06.093 に答える
3

適切な出発点は、低断片化ヒープを有効にして、まだ断片化されているかどうかを確認することです。

  HANDLE heaps[1025];
  DWORD nheaps = GetProcessHeaps((sizeof(heaps) / sizeof(HANDLE)) - 1, heaps);
  for (DWORD i = 0; i < nheaps; ++i) {
    ULONG  enableLFH = 2;
    HeapSetInformation(heaps[i], HeapCompatibilityInformation, &enableLFH, sizeof(enableLFH));
  }

この新しく導入されたメモリ マネージャーは、Vista/Server 2008 ではデフォルトで有効になっています。したがって、新しいサーバー OS の方が世界が優れていると判断した場合、これが理由である可能性があります。

低断片化ヒープは、Windows 2000 のサービス パックで導入されましたが、Windows Vista まで積極的に有効にする必要があります。

メモリの概要を簡単に示し、断片化が発生した場合に適切な概要を示すツールvmmapがあります。

于 2009-10-20T07:21:01.490 に答える
0

時間やリクエスト数に基づいて再起動をスケジュールするのではなく、ヒープを調べて、メモリの最大連続ブロックが特定のレベルを下回ったときに断片化がいつレベルに達したかを確認できます。すべてのメモリが使い果たされたときではなく、ヒープ内の最大の空き連続スペースのサイズよりも大きなオブジェクトを割り当てようとしたときに、メモリエラーが発生します。

VirtualQueryExを使用してヒープを調べ、最大の空き連続領域を見つけることができます。これを行う方法の例については、この記事を参照してください。

于 2009-10-20T07:15:29.110 に答える
0

明らかな回避策は、過去に考案された古いソリューションを掘り起こすことです。たとえば、生のポインターではなく、移動可能なオブジェクトへの不透明なハンドル。これにより、ヒープを最適化できます。

于 2009-10-20T07:55:04.727 に答える