現代のオペレーティングシステムは一般に仮想メモリ管理(Virtual Memory Management)メカニズムを採用しており、これにはプロセッサ内のMMU(Memory Management Unit)によるサポートが必要です。まず、PA と VA の概念を紹介します。
プロセッサに MMU がない場合、または MMU はあるが有効になっていない場合、CPU 実行ユニットによって送信されたメモリ アドレスが直接プロセッサに送信されます。下図に示すように、チップのピンをメモリチップ(以下、仮想メモリと区別するため物理メモリと呼びます)に渡すことをPA(Physical Address、以下PA)と呼びます。
プロセッサで MMU が有効になっている場合、CPU 実行ユニットによって送信されたメモリ アドレスは MMU によってインターセプトされ、CPU 実行ユニットからのアドレスはCPU から MMU への接続は仮想アドレス (以下、VA と呼びます) と呼ばれ、MMU はこのアドレスを別のアドレスに変換して CPU チップの外部アドレス ピンに送信します。つまり、図に示すように、VA を PA にマッピングします。下の図。
32ビットプロセッサの場合、内部アドレスバスは32ビットでCPU実行ユニットに接続されます(図では4本のアドレス線のみが概略的に描かれています)が、MMU変換後の外部アドレスバスは必ずしも32であるとは限りません-少し。つまり、仮想アドレス空間と物理アドレス空間は独立しています。32 ビット プロセッサの仮想アドレス空間は 4GB ですが、物理アドレス空間は 4GB より大きくても小さくても構いません。
MMUはVAをページ単位でPAにマッピングします。32ビットプロセッサのページサイズは通常4KBです。たとえば、MMU はマッピング項目を通じて VA の 0xb7001000 ~ 0xb7001fff のページを PA の 0x2000 ~ 0x2fff のページにマッピングできます。CPU 実行ユニットが仮想アドレス 0xb7001008 にアクセスする場合、アクセスされる実際の物理アドレスは 0x2008 です。物理メモリ内のページは、物理ページまたはページ フレームと呼ばれます。仮想メモリのどのページが物理メモリのどのページ フレームにマップされるかは、ページ テーブル (ページ テーブル) によって記述されます。ページ テーブルは物理メモリに格納されており、MMU はページ テーブルを検索して、VA がどの PA を使用するかを決定します。にマッピングされます。
3. プロセス アドレス空間
プロセス アドレス空間x86 プラットフォームの仮想アドレス空間は 0x0000 0000~0xffff ffff で、一般的に最初の 3GB (0x0000 0000~0xbfff ffff) がユーザー空間、最後の 1GB (0xc000 0000~0xffff ffff) がカーネル空間です。
テキストセグメント、.textセグメント、.rodataセグメント、.pltセグメントなどを含みます。 /bin/bash からメモリにロードされ、アクセス権限は r-x です。
データセグメント (.data セグメント、.bss セグメントなどを含む)また、/bin/bash からメモリにロードされ、アクセス権限は rw- です。
ヒープ: ヒープとは、単にコンピューターのメモリに残っている領域のことで、ここで malloc 関数が動的にメモリを割り当てます。メモリを動的に割り当てると、ヒープ スペースがより高いアドレスに向かって拡大する可能性があります。ヒープ空間のアドレスの上限は Break と呼ばれ、ヒープ空間を高いアドレスに拡張するには、新しい仮想メモリ ページを物理メモリにマップするために、システム コール brk によって実現されます。また、関数は brk を呼び出してカーネル メモリからの割り当てを要求します。
スタック: スタックは特定のメモリ領域であり、高アドレス部分はプロセスの環境変数とコマンドラインパラメータを保存し、低アドレス部分は関数スタックフレームとスタックスペースを保存します。実際のアプリケーションでは大量のメモリを動的に割り当てることは珍しくありませんが、各層には数十の深い関数呼び出しがあるため、明らかにヒープ領域ほどの拡張の余地はありません。の呼び出しに多くのローカル変数が含まれることは非常にまれです。
プログラムを書くときにメモリ割り当てに注意しないと、ヒープやスタックで以下の問題が発生する可能性があります:
メモリリーク: 関数内で malloc を渡す場合ヒープ内にスペースを配置し、それを保存するためにスタック上にポインタ変数を宣言すると、関数が終了すると、ポインタ変数を含む関数のメンバー変数が解放され、スペースは回復されず、回復できません。解放されました。時間が経つと、次のようなメモリ リークの問題が発生する可能性があります。
スタック オーバーフロー: スタックに多すぎるデータ (大きな構造体や配列など) を置くと、「スタック オーバーフロー」問題が発生し、プログラムが終了する可能性があります。この問題を回避するには、そのような変数を宣言するときに、malloc を使用してヒープ領域を適用する必要があります。
ワイルドポインターとセグメンテーションフォルト: ポインターが指すスペースが解放されている場合、そのポインターを使用して解放されたスペースにアクセスしようとすると、「セグメントフォルト」の質問が発生します。この時点で、ポインタはワイルド ポインタになっているため、ワイルド ポインタは時間内に手動でクリアする必要があります。
仮想メモリ管理は、物理メモリのアクセス許可を制御できます。物理メモリ自体にはアクセスが制限されず、任意のアドレスの読み取りと書き込みが可能ですが、オペレーティング システムでは、異なるページに異なるアクセス権が必要になります。これは、CPU モードと MMU のメモリ保護メカニズムを使用することで実現されます。
仮想メモリ管理の主な機能は、各プロセスが独立したアドレス空間を持つことができるようにすることです。いわゆる独立したアドレス空間とは、異なるプロセスの同じ VA が MMU によって異なる PA にマッピングされることを意味し、あるプロセスの任意のアドレスにアクセスすると、他のプロセスのデータにアクセスできなくなります。これにより、どのプロセスも不正なメモリアクセスが発生することになります。命令や悪意のあるコードが他のプロセスのデータを誤って書き換えたり、他のプロセスの動作に影響を与えたりすることがないため、システム全体の安定性が確保されます。一方、各プロセスは仮想アドレス空間全体を排他的に所有していると考えるため、各プロセスのアドレス範囲が競合するかどうかを考慮する必要がなく、リンカとローダの実装が容易になります。
システムが同時に多数のプロセスを実行している場合、各プロセスに割り当てられたメモリの合計が、実際に利用可能な物理メモリよりも大きくなる場合がありますが、この場合でも仮想メモリ管理により各プロセスは正常に実行されます。各プロセスには仮想メモリ ページのみが割り当てられるため、これらのページのデータを物理ページにマッピングしたり、物理ページを占有せずにディスクに一時的に保存したりすることができます。ディスク上の仮想メモリ ページは一時的に保存されます。ディスク パーティション、またはスワップ デバイスと呼ばれるディスク ファイルの場合もあります。 物理メモリが十分ではない場合、使用頻度の低い物理ページのデータは一時的にスワップ デバイスに保存されます。その後、その物理ページは空きとみなされ、プロセスに再割り当てされます。このプロセスはスワップ アウト (ページ アウト) と呼ばれます。 )。プロセスがスワップアウトされたページを使用したい場合、スワップ デバイスから物理メモリにロードし直します。これはスワップ イン (ページ イン) と呼ばれます。スワップアウト操作とスワップイン操作はまとめてページングと呼ばれ、次のようになります:
以上が仮想メモリ管理の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。