web-dev-qa-db-ja.com

malloc中にカーネルで何が起こりますか?

面接でこの質問をされました。彼らが知りたかったのは、ユーザーがmalloc(4)を呼び出して4バイトのメモリを割り当てるとき、オペレーティングシステム(Linux)はどのように応答するかということでした。このシステムコールに応答するサブシステムはどれですか。

私は彼にmalloc()がメモリ管理サブシステムによって処理されることを伝えました。 malloc()実装は、空きメモリ(物理メモリ)のリストを調べ、それを空きリストと呼び、4バイト以上の適切なチャンクを見つけます。そのようなチャンクが見つかると、空きリストから削除され、使用済みリストに追加されます。次に、その物理メモリがプロセスヒープvma構造体にマップされます。彼はこの回答に満足しているようには見えませんでしたが、バディシステムはこれにどのように適合しますか?どんな助けでも大歓迎です。

48
liv2hak

ユーザー空間アプリケーションがmalloc()を呼び出す場合、その呼び出しはカーネルに実装されていません。代わりに、それはライブラリー呼び出しです(実装されたglibcなど)。

短いバージョンでは、glibcのmalloc実装はbrk()/sbrk()システムコールからメモリを取得するか、mmap()を介して匿名メモリを取得します。これにより、glibcに(仮想メモリアドレスに関して)連続した大きなメモリチャンクが提供されます。malloc実装は、さらに小さなチャンクでスライスおよびダイシングし、アプリケーションに渡します。

ここ は、多数のリンクとともにアイデアを提供する小さなmalloc実装です。

物理メモリについてはまだ何も気にしていないことに注意してください。これは、プロセスデータセグメントがbrk()/sbrk()またはmmap()によって変更されたときにカーネル仮想メモリシステムによって処理されます。メモリが参照されたとき(メモリへの読み取りまたは書き込みによって)。

要約する:

  1. malloc()は、管理されているメモリを検索して、割り当て要件を満たす未使用のメモリがあるかどうかを確認します。
  2. 失敗した場合、malloc()はプロセスデータセグメントを拡張しようとします(sbrk()/brk()または場合によってはmmap())。 sbrk()はカーネルで終了します。
  3. カーネルのbrk()/sbrk()呼び出しは、プロセスのstruct mm_structの一部のオフセットを調整するため、プロセスデータセグメントが大きくなります。最初は、データセグメントの拡張によって提供された追加の仮想アドレスにマップされた物理メモリはありません。
  4. マップされていないメモリが最初にタッチされると(mallocの実装による読み取り/書き込みの可能性があります)、障害ハンドラーが起動してカーネルにトラップされ、カーネルがマップされていないメモリに物理メモリを割り当てます。
62
nos

回答に誤りがあります-mallocは物理メモリを直接処理しませんページ仮想メモリ -を扱っていますが、そこにあるすべてのアーキテクチャに当てはまるかどうかはわかりません。

プログラムがメモリを割り当てようとして、空きリストに要求されたサイズ以上のチャンクが含まれていない場合、新しいページ全体が割り当てられます。ページサイズはアーキテクチャに依存します(x86では4096バイト)。ページの割り当てはカーネルのみが実行できるものであるため、mallocの呼び出しによってシステムコールが発生する場合があります。次に、新しいアドレスがフリーリストに追加され、mallocはその実装に従ってフリーリストを操作します(たとえば、glibcをチェックします)。

10
jweyrich