ヒープ(データ構造) を使用して ヒープ(動的メモリ割り当て) を実装すると常に想定していましたが、間違っていると言われました。
ヒープ(たとえば、通常のmalloc
ルーチンやWindowsのHeapCreate
などによって実装されるもの)は、通常、どのように実装されますか?彼らはどのようなデータ構造を使用していますか?
オンラインで検索しているときに、ヒープの実装方法の説明がトンあるのを見ました厳しい制限付き。
いくつか例を挙げると、実装方法の説明をたくさん見てきました。
そしてそれは面白いです、彼らはすべて難しい質問を避けます:
「通常の」汎用ヒープ(malloc
、HeapCreate
の背後にあるものなど)はどのように実装されますか?
彼らはどのようなデータ構造(そしておそらくアルゴリズム)を使用していますか?
アロケータは非常に複雑になる傾向があり、実装方法が大きく異なることがよくあります。
1つの一般的なデータ構造またはアルゴリズムの観点からそれらを実際に説明することはできませんが、いくつかの一般的なテーマがあります。
ソースコードをチェックしたい場合、 jemalloc は最新の高性能アロケーターであり、他の一般的なアロケーターの複雑さを代表するものでなければなりません。 TCMalloc は、もう1つの一般的な汎用アロケーターであり、そのWebサイトではすべての厄介な実装の詳細が説明されています。 Intelの スレッドビルディングブロック には、高い同時実行性のために特別に構築されたアロケータがあります。
Windowsと* nixの間には興味深い違いが1つあります。 * nixでは、アロケーターはアプリが使用するアドレス空間を非常に低レベルで制御します。 Windowsでは、基本的に、独自のアロケータのベースとなる、コースグレインの低速アロケータVirtualAlloc
があります。
これにより、* nix互換のアロケーターは、通常、malloc
/free
の実装を直接提供します。この実装では、すべてに1つのアロケーターのみを使用すると想定されます(そうでない場合は、互いに踏みにじられます)。一方、Windows固有のアロケーターは、malloc
/free
をそのままにして、追加の機能を提供し、調和して使用できます(たとえば、HeapCreateを使用して、他のユーザーと一緒に機能するプライベートヒープを作成できます)。
実際には、この柔軟性のトレードにより、* nixアロケーターはパフォーマンス面で小さな足がかりになります。アプリがWindowsで意図的に複数のヒープを使用するのを見るのは非常にまれです-ほとんどの場合、それぞれが独自のmalloc
/free
を持つ異なるランタイムを使用する異なるDLLが原因で、多くの原因となる可能性があります。どのヒープからメモリが発生したかを追跡することに熱心でない場合は、頭痛の種になります。
注:次の回答は、仮想メモリを備えた一般的な最新のシステムを使用していることを前提としています。 CおよびC++標準は仮想メモリを必要としません。したがって、もちろん、この機能がないハードウェアでは、このような仮定に頼ることはできません(たとえば、GPUには通常この機能がなく、PICのような非常に小さなハードウェアもありません)。
これは、使用しているプラットフォームによって異なります。ヒープは非常に複雑な獣になる可能性があります。単一のデータ構造のみを使用するわけではありません。また、「標準」のデータ構造はありません。ヒープコードが配置されている場所も、プラットフォームによって異なります。たとえば、ヒープコードは通常、UnixボックスのCランタイムによって提供されます。ただし、通常はWindowsのオペレーティングシステムによって提供されます。
brk
またはsbrk
です)。多くのヒープは、メモリをオペレーティングシステムに戻す代わりに、プログラムが適切に使用しなくなったメモリを再利用しようとするだけであり、メモリをシステムに戻そうとはしません。 sbrk
(VirtualAlloc
)に相当するものにはこの制限がないため、これはWindowsではあまり一般的ではありません。 (ただし、sbrk
と同様に、非常に高価であり、ページサイズとページ揃えのチャンクのみを割り当てるなどの注意点があります。したがって、ヒープはできるだけまれに呼び出しを試みます)RtlHeap
は、さまざまな既知のブロックサイズに対して、このような多数のデータ構造を維持しています。 (たとえば、サイズ16のブロック用に1つあります)RtlHeapはこれらを「ルックアサイドリスト」と呼びます。主要なプラットフォームで採用されている一般的な割り当て戦略について説明している私が見つけた最良の参考資料は、Robertによる本 CおよびC++でのセキュアコーディング)です。シーコード 。第4章はすべて、ヒープデータ構造(およびユーザーが上記のヒープシステムを誤って使用した場合に発生する問題)に特化しています。