malloc() は内部的にどのように実装されていますか? [重複] 質問する

malloc() は内部的にどのように実装されていますか? [重複] 質問する

内部的にどのように動作するのか説明できる人はいますかmalloc()?

私は時々システムコールをstrace programたくさん見たり、それがどのように使用されているかについて話したりしていますが、それ以上のことはしていません。sbrkman sbrkmalloc()

ベストアンサー1

システムsbrkコールは、データ セグメントの「境界」を移動します。つまり、プログラムがデータを読み書きできる領域の境界を移動します (拡大または縮小しますが、私の知る限り、mallocこの方法ではメモリ セグメントがカーネルに返されることはありません)。それとは別に、mmapファイルをメモリにマップするために使用される もありますが、メモリを割り当てるためにも使用されます (共有メモリを割り当てる必要がある場合は、mmapこれを使用します)。

したがって、カーネルからメモリを増やすには、sbrkとという2 つの方法がありますmmap。カーネルから取得したメモリを整理する方法にはさまざまな戦略があります。

単純な方法の 1 つは、特定の構造サイズ専用の「バケット」と呼ばれるゾーンに分割することです。たとえば、実装mallocでは 16、64、256、1024 バイトの構造のバケットを作成できます。malloc特定のサイズのメモリを要求すると、その数値が次のバケット サイズに切り上げられ、そのバケットから要素が提供されます。より大きな領域が必要な場合は、カーネルで直接割り当てるためにmallocを使用できますmmap。特定のサイズのバケットが空の場合は、新しいバケット用にスペースを増やすためにmallocを使用できます。sbrk

mallocさまざまな設計があり、malloc速度、オーバーヘッド、断片化/スペース効率の回避の間で妥協する必要があるため、実装の正しい方法はおそらく 1 つではありません。たとえば、バケットの要素が不足した場合、実装ではより大きなバケットから要素を取得し、それを分割して、要素が不足しているバケットに追加します。これは非常にスペース効率が高くなりますが、すべての設計で可能というわけではありません。/ 経由で別のバケットを取得するだけであれば、より高速で簡単かもしれませんが、スペース効率はそれほど高くありませsbrkmmap。また、設計では、当然のことながら、「解放」によって何らかの方法でスペースを再び利用できるようにする必要があることを考慮する必要がありますmalloc。メモリを再利用せずに配布するだけではいけません。

ご興味があれば、OpenSER/Kamailio SIP プロキシには 2 つのmalloc実装があります (共有メモリを多用し、システムがmalloc共有メモリをサポートしていないため、独自の実装が必要です)。参照:https://github.com/OpenSIPS/opensips/tree/master/mem

また、GNU libcmalloc実装、しかし、それは非常に複雑だと思います。

おすすめ記事