アロケータは非常に複雑になる傾向があり、実装方法が大きく異なることがよくあります。
1 つの共通のデータ構造またはアルゴリズムの観点からそれらを実際に説明することはできませんが、いくつかの共通のテーマがあります。
- メモリは大きなチャンクでシステムから取得されます。多くの場合、一度に数メガバイトです。
- これらのチャンクは、割り当てを実行すると、さまざまな小さなチャンクに分割されます。割り当てたサイズとまったく同じではありませんが、通常は特定の範囲 (200 ~ 250 バイト、251 ~ 500 バイトなど) です。場合によっては、これが多層化され、実際のリクエストの前に「中程度のチャンク」のレイヤーが追加される場合があります。
- どの「大きなチャンク」から分割するかを制御することは、非常に困難で重要なことです。これは、メモリの断片化に大きく影響します。
- これらの範囲ごとに、1 つまたは複数のフリー プール (別名「フリー リスト」、「メモリ プール」、「ルックアサイド リスト」) が維持されます。場合によっては、スレッドローカル プールも。これにより、同様のサイズの多くのオブジェクトの割り当て/割り当て解除のパターンを大幅に高速化できます。
- 大規模な割り当ては、RAM を大量に浪費せず、プールされたとしてもあまりプールされないように、少し異なる方法で処理されます。
いくつかのソース コードを確認したい場合、jemallocは最新の高性能アロケーターであり、他の一般的なアロケーターの複雑さを代表するものである必要があります。TCMallocは、もう 1 つの一般的な汎用アロケーターであり、その Web サイトには、すべての面倒な実装の詳細が記載されています。Intel のThread Building Blocksには、高い同時実行性のために特別に構築されたアロケーターがあります。
Windows と *nix の間には、興味深い違いが 1 つあります。*nix では、アロケーターは、アプリが使用するアドレス空間を非常に低レベルで制御します。VirtualAlloc
Windows では、基本的に、独自のアロケーターのベースとなる粗粒度の遅いアロケーターがあります。
これにより、* nix 互換のアロケーターは通常、すべてに 1 つのアロケーターのみを使用すると想定される / 実装を直接提供します(そうmalloc
しfree
ないと、お互いを踏みにじる可能性があります)。、調和して使用できます (たとえば、HeapCreate を使用して、他のヒープと一緒に機能するプライベート ヒープを作成できます)。malloc
free
実際には、この柔軟性のトレードオフにより、*nix アロケーターはパフォーマンス面でわずかに有利になります。アプリが Windows で意図的に複数のヒープを使用することは非常にまれです。ほとんどの場合、それぞれが独自のmalloc
/free
を持つ異なるランタイムを使用する異なる DLL が原因であり、どのヒープを追跡することに熱心でない場合、多くの頭痛の種となる可能性があります。いくつかの記憶が生まれました。