1. ホーム
  2. c

[解決済み] malloc()は内部でどのように実装されているのですか?重複

2022-08-05 11:43:38

質問

どなたか、どのように malloc() が内部でどのように動作しているか説明できますか?

私は時々 strace program をよく見かけますが sbrk システムコールを行い man sbrk で使用されることについて話す。 malloc() で使われていることを述べていますが、それ以上ではありません。

どのように解決するのですか?

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

つまり、カーネルからより多くのメモリを得るための方法が2つあるわけです。 sbrkmmap . カーネルから得たメモリをどのように整理するかについては、様々な戦略があります。

1つの素朴な方法は、しばしば "bucket" と呼ばれる、特定の構造サイズ専用のゾーンに分割することです。例えば malloc の実装では、16、64、256、1024 バイトの構造体用のバケットを作成することができます。もしあなたが malloc にあるサイズのメモリを要求すると、その数は次のバケットサイズに切り上げられ、そのバケットから要素を取得します。より大きな領域が必要な場合は malloc を使うことができます。 mmap を使って、カーネルと直接アロケートすることができます。もし、あるサイズのバケットが空であれば malloc を使うことができます。 sbrk を使って、新しいバケツのためのより多くのスペースを得ることができます。

そこには様々な malloc を実装する真の方法はないでしょう。 malloc を実装する方法は、速度、オーバーヘッド、断片化/空間的効果の回避の間で妥協する必要があるからです。たとえば、バケツの要素がなくなった場合、ある実装はより大きなバケツから要素を取得し、それを分割して要素がなくなったバケツに追加するかもしれません。これは非常にスペース効率が良いのですが、すべての設計で可能なわけではありません。もし、別のバケツを sbrk / mmap というように、より速く、より簡単かもしれませんが、スペース効率は良くありません。また、デザインはもちろん、"free" が次のようなスペースを利用できるようにする必要があることも考慮しなければなりません。 malloc に再び使用できるようにする必要があります。メモリを再利用せずにただ配ることはできません。

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

それから、あなたはまた GNU libc malloc の実装を見ることができます。 がありますが、これは非常に複雑です。