GNU/Linux >> Linux の 問題 >  >> Linux

malloc() が mmap() と brk() を同じ意味で呼び出すのはなぜですか?

mmap (MAP_ANONYMOUSで使用する場合 ) プロセスの仮想アドレス空間内のどこにでも配置でき、後で割り当てを解除できる RAM のチャンクを割り当てます (munmap を使用) ) 他のすべての割り当てとは無関係です。

brk 仮想アドレス空間の単一の連続した「アリーナ」の終了アドレスを変更します。このアドレスが増加すると、アリーナにより多くのメモリが割り当てられ、減少すると、アリーナの最後でメモリの割り当てが解除されます。したがって、brk で割り当てられたメモリ アリーナの最後にアドレスの連続範囲がある場合にのみ、オペレーティング システムにリリースできます。 このプロセスではもう必要ありません。

brk の使用 小さな割り当ての場合、および mmap 大きな割り当ての場合、小さな割り当てはすべて同じ寿命を持つ可能性が高く、大きな割り当ては他の割り当ての寿命と相関しない寿命を持つ可能性が高いという仮定に基づくヒューリスティックです。そのため、大きな割り当てはシステム プリミティブを使用して他のものから独立して割り当てを解除できるようにし、小さな割り当てはそうでないプリミティブを使用します。

このヒューリスティックはあまり信頼できません。 malloc の現在の世代 私の記憶が正しければ、実装は brk で完全にあきらめました mmap を使用 全てにおいて。 malloc あなたが見ていると思う実装 (あなたのタグに基づく GNU C ライブラリーのもの) は非常に古く、主に使用され続けています。>おそらく しかし、確かに


では、大きなサイズのメモリを割り当てるときに、malloc が mmap を呼び出すのはなぜでしょうか?

簡単な答えは、効率の向上です。 Linux の新しい実装、およびそれらに付属する更新されたメモリ割り当てアルゴリズムについて。ただし、これは非常に実装に依存するトピックであり、議論されている特定の Linux OS のヴィンテージやフレーバーが異なると、その理由と理由が大きく異なることに注意してください。

これは、低レベルのパーツ mmap() に関するかなり最近の記事です。 そして brk() Linux メモリ割り当てで再生します。また、それほど最近ではありませんが、関連性のある Linux Journal の記事には、ここでのトピックに非常に適した内容が含まれています。これには次のようなものがあります:

<ブロック引用>

非常に大きな要求の場合、malloc() は mmap() システム コールを使用して、アドレス指定可能なメモリ空間を見つけます。 このプロセスは、メモリの断片化による悪影響を軽減するのに役立ちます メモリの大きなブロックが解放されますが、それらの間にある最近割り当てられた小さなブロックと割り当てられたスペースの最後によってロックされます。この場合、実際には、ブロックが brk() で割り当てられていれば、プロセスがブロックを解放したとしても、システムは使用できないままでした。
(私のものを強調)

brk()について :
ちなみに、"...mmap() は Unix の初期のバージョンには存在しませんでした。brk() 当時、プロセスのデータ セグメントのサイズを増やす唯一の方法でした。 mmap() を備えた Unix の最初のバージョンは 80 年代半ばの SunOS で、最初のオープンソース バージョンは 1990 年の BSD-Reno でした。 "。それ以来、メモリ割り当てアルゴリズムの最新の実装は、多くの改良を加えてリファクタリングされ、brk() を使用する必要性が大幅に減少しました。 .


Linux
  1. Linuxサーバーとは何ですか?なぜあなたのビジネスにはLinuxサーバーが必要なのですか?

  2. パスワードハッシュとその必要性

  3. Linux – Linuxは、物理的にインストールしたメモリよりも多くのメモリと少ないメモリの両方を表示するのはなぜですか?

  1. malloc(0) は何を返しますか?

  2. brk() システムコールは何をしますか?

  3. mmap() がシーケンシャル IO よりも速いのはなぜですか?

  1. Env X =(){:;}; Command’Bashは、なぜそれが安全でないのですか?

  2. なぜ`exit&`が機能しないのですか?

  3. x86 と x86_64 の Linux システムコール番号が異なるのはなぜですか?