内部的にどのように動作するのか説明できる人はいますかmalloc()
?
私は時々システムコールをstrace program
たくさん見たり、それがどのように使用されているかについて話したりしていますが、それ以上のことはしていません。sbrk
man sbrk
malloc()
ベストアンサー1
システムsbrk
コールは、データ セグメントの「境界」を移動します。つまり、プログラムがデータを読み書きできる領域の境界を移動します (拡大または縮小しますが、私の知る限り、malloc
この方法ではメモリ セグメントがカーネルに返されることはありません)。それとは別に、mmap
ファイルをメモリにマップするために使用される もありますが、メモリを割り当てるためにも使用されます (共有メモリを割り当てる必要がある場合は、mmap
これを使用します)。
したがって、カーネルからメモリを増やすには、sbrk
とという2 つの方法がありますmmap
。カーネルから取得したメモリを整理する方法にはさまざまな戦略があります。
単純な方法の 1 つは、特定の構造サイズ専用の「バケット」と呼ばれるゾーンに分割することです。たとえば、実装malloc
では 16、64、256、1024 バイトの構造のバケットを作成できます。malloc
特定のサイズのメモリを要求すると、その数値が次のバケット サイズに切り上げられ、そのバケットから要素が提供されます。より大きな領域が必要な場合は、カーネルで直接割り当てるためにmalloc
を使用できますmmap
。特定のサイズのバケットが空の場合は、新しいバケット用にスペースを増やすためにmalloc
を使用できます。sbrk
malloc
さまざまな設計があり、malloc
速度、オーバーヘッド、断片化/スペース効率の回避の間で妥協する必要があるため、実装の正しい方法はおそらく 1 つではありません。たとえば、バケットの要素が不足した場合、実装ではより大きなバケットから要素を取得し、それを分割して、要素が不足しているバケットに追加します。これは非常にスペース効率が高くなりますが、すべての設計で可能というわけではありません。/ 経由で別のバケットを取得するだけであれば、より高速で簡単かもしれませんが、スペース効率はそれほど高くありませsbrk
んmmap
。また、設計では、当然のことながら、「解放」によって何らかの方法でスペースを再び利用できるようにする必要があることを考慮する必要がありますmalloc
。メモリを再利用せずに配布するだけではいけません。
ご興味があれば、OpenSER/Kamailio SIP プロキシには 2 つのmalloc
実装があります (共有メモリを多用し、システムがmalloc
共有メモリをサポートしていないため、独自の実装が必要です)。参照:https://github.com/OpenSIPS/opensips/tree/master/mem
また、GNU libcmalloc
実装、しかし、それは非常に複雑だと思います。