2013-11-14 4 views
5

私はシステムソフトウェアの教員です。今私はWindows用のメモリマネージャを開発しています。それが正常に動作しますメモリ管理の目的で複数のヒープを使用する利点はありますか?

HANDLE heap = HeapCreate(0, 0, 0); 

void* hmalloc(size_t size) 
{ 
    return HeapAlloc(heap, 0, size); 
} 

void hfree(void* memory) 
{ 
    HeapFree(heap, 0, memory); 
} 

int main() 
{ 
    int* ptr1 = (int*)hmalloc(100*sizeof(int)); 
    int* ptr2 = (int*)hmalloc(100*sizeof(int)); 
    int* ptr3 = (int*)hmalloc(100*sizeof(int)); 

    hfree(ptr2); 
    hfree(ptr3); 
    hfree(ptr1); 

    return 0; 
} 

:ここmalloc()free()の私の単純な実装です。しかし、私は複数のヒープを使用する理由は理解できませんか?さて、ヒープにメモリを割り当て、割り当てられたメモリチャンクにアドレスを取得できます。しかしここで私はONEヒープを使用します。複数のヒープを使用する理由はありますか?多分マルチスレッド/マルチプロセスアプリケーションのために?説明してください。

+0

あなたの実装であれば、なぜ3を作成したのか分かりませんか? –

+0

私はただ何かを試しました。それはいくつかの問題を引き起こしますか? – Netherwire

+1

はい、私の答えを見てください。 C++ではなくCを使用していますので、デストラクタが呼び出されていることを確認する必要があります。 –

答えて

2

あなたはいくつかの良い考えを持っていますが、これはCで動作しますが、C++ではデストラクタがあります。実行するのは非常に重要です。

すべての型は、論理的に「何もしない」というコンストラクタ/デストラクタを持つと考えることができます。

これはアロケータに関するものです。 2つの累乗を使用して要素を整列して再利用する「バディアルゴリズム」を参照してください。

どこかに4バイトを割り当てると、私のアロケータは4バイトの割り当てのためだけに4kbのセクションを割り当てます。そうすれば、別のブロックを追加する必要があれば、ブロックに1024の4バイトのものを収めることができます。

4kbブロックに4KBブロックを割り当てても、大きな要求に対して別のブロックが割り当てられることはありません。

これは大きなものを一緒に保持できることを意味します。私が17バイト、次に13バイト、1バイト、13バイトが解放されたら、そこには< = 13バイトのものしか置くことができません。

したがって、私が2.5kbのブロックを必要とするならば、私は2kの最小のパワー(この場合は4kb)に割り当てることができます。その後スロットを< = 4kbのアイテムに使用してください。

これはガベージコレクションのためのものではありません。これは、自分のアロケータを使ってOSへの呼び出しを停止することができます(newとdeleteの既定の実装に応じて、新しい/削除をすばやく行うことができます。

ヒープ圧縮は非常に異なります。ヒープを指すすべてのポインタのリスト、またはメモリグラフ全体(たとえばspits Javaなど)をトラバースする何らかの方法が必要です。そのことを指摘しているすべてのものを現在の場所に更新することができます。

+0

これは私をとても助けました。私はあなたのアドバイスを理解し、それを教師に説明しました。彼は同意した。 – Netherwire

10

複数のヒープ/カスタムアロケータを使用する主な理由は、メモリ管理を改善するためです。通常、多くの新しい/削除の後、メモリは断片化し、アプリケーションのパフォーマンスが低下します(また、アプリケーションはより多くのメモリを消費します)。より制御された環境でメモリを使用すると、ヒープの断片化を減らすことができます。

また、アプリケーションでメモリリークを防ぐために、割り当てたヒープ全体を解放するだけで、そこに割り当てられているすべてのオブジェクトを解放する必要はありません。

また、厳密に割り当てられたオブジェクトの場合もあります。たとえば、リストを持っていれば、小さな専用のヒープにすべてのノードを割り当てることができ、ノードを反復するときにキャッシュミスが少なくなるため、

編集:メモリ管理は難しい話題ですが、場合によっては正しく行われません。 Andrei Alexandrescu氏はある時点で話をしていましたが、カスタムアロケータをデフォルトのものに置き換えるアプリケーションによっては、アプリケーションのパフォーマンスが向上したという。

+0

malloc/freeは通常、断片化を減らすために自動的にヒープを作成/解放しますか? – Netherwire

+0

あなたは単に「ヒープを削除する」ことはできません。あなたはそれを解放することができますが、そうしなくてはなりません。あなたがそれらの中のものを破壊しない巨大なスワスを削除すると、destroyはデストラクタを使用します(void以外のものは空以外には何もありません)、コンテナ構造などがあれば他のヒープへのポインタを持つかもしれません。彼はC++と言う。 –

+0

'メモリリークを防ぐ' - 疑問があるもの –

2

理由は、プログラムを内部的に実行する必要があるというシナリオです。シミュレーションコードを実行する。独自のヒープを作成することで、そのヒープにセキュリティ上の理由からデフォルトで実行権が無効にされるようにすることができます。 (Windows)

0

私がこれまでに複数のヒープを使用したのは、複雑なデータ構造を構築するプログラムを書いたときだけでした。データ構造を解放し、個々のノードを解放することでデータ構造を解放することは自明ではありませんでしたが、幸い私にとっては、(特定の操作を実行している間に)プログラムは一時的にデータ構造しか必要としませんでした。私がもはやそれを必要としなくなったときに、私はHeapDestroyへの一回の呼び出しでそれを解放することができるようにデータ構造を作りました。

関連する問題