ホームページ > 記事 > システムチュートリアル > Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。
今日は Linux
のメモリ管理について勉強します。
CURD に精通しているビジネス学生にとって、メモリ管理は遠い存在のように思えます。しかし、この知識点はあまり人気がありませんが(学習してもまったく使用しない人が多いと推測されます)、基本中の基礎であることは間違いありません。
記事内のサンプル画像はすべて私が描いたものです。絵を描くのはコーディングよりも時間がかかりますが、言葉よりも絵を見たほうが誰でも直感的に理解できるので、今でも描いています。高解像度のサンプル写真が必要な学生向けに、記事の最後に入手方法があります。
より実用的な言い方をすると、面接中にうっかりこの知識を知っていることを明らかにし、1 つ、2 つ、3 つを話すことができれば、面接官はあなたにさらに興味を持ち、合格する可能性が高くなります。昇進、昇給、仕事など、人生の頂点に一歩近づきます。前提条件: この記事の技術的な内容について説明する前提は、オペレーティング システム環境が
x86 アーキテクチャの 32 ビット
Linux システムであることです。
システム メモリ リソースを最大限に活用および管理するために、Linux は仮想メモリ管理テクノロジを使用します。仮想メモリ技術を使用することで、各プロセスは相互に干渉しない 4GB の仮想アドレス空間を持ちます。
プロセスの初期化の割り当てと操作は、この「仮想アドレス」に基づいて行われます。プロセスが実際にメモリ リソースにアクセスする必要がある場合にのみ、仮想アドレスと物理アドレスの間のマッピングが確立され、物理メモリ ページが転送されます。
不適切なたとえで言えば、この原理は実際には現在の XX ネットワーク ディスクと同じです。ネットワーク ディスク容量が 1TB の場合、一度にそのような大きな容量が与えられると本当に思いますか?それはまだ若すぎます。スペースは、物を入れたときにのみ割り当てられ、入れた分だけ実際のスペースが割り当てられます。しかし、あなたとあなたの友人は両方とも 1TB のスペースを持っているようです。
ユーザー空間カーネル空間
######実在住所######
ユーザー空間であろうとカーネル空間であろうと、使用されるアドレスは仮想アドレスであることは、上の章ですでにわかっています。プロセスが実際にメモリにアクセスする必要がある場合、カーネルの "リクエストページングメカニズム」を物理メモリページに転送します。セグメントページメモリ管理アドレス変換
Linux
カーネルは物理メモリを次の 3 つの管理領域に分割します。
DMAメモリ領域。 0MB ~ 16MB のメモリ ページ フレームが含まれます。これは、
DMA を介して古い
ISA ベースのデバイスで使用でき、カーネルのアドレス空間に直接マップされます。
物理メモリ領域の分割
0x00000000 から
0xBFFFFFFF で、総容量は 3G です。 。
5の異なるメモリ領域に分割されます。アクセス属性とは、「読み取り可能、書き込み可能、実行可能など」を指します。
データセグメント
BSSセグメント
BSS
セクションには初期化されていないグローバル変数が含まれており、メモリ内のすべてのbss セクションは 0 に設定されます。
ヒープは、プロセス操作中に動的に割り当てられるメモリ セグメントを格納するために使用されます。そのサイズは固定されておらず、動的に拡張または縮小できます。プロセスが malloc などの関数を呼び出してメモリを割り当てると、新しく割り当てられたメモリがヒープに動的に追加されます (ヒープが拡張されます)。free などの関数を使用してメモリを解放すると、解放されたメモリがヒープから削除されます。 (ヒープが削減されます)。
スタック スタック
スタックは、プログラムを保存するためにユーザーによって一時的に作成されるローカル変数、つまり関数で定義された変数です (ただし、static
で宣言された変数は含まれません。静的とは、変数をスタックに保存することを意味します)データセグメント)。さらに、関数が呼び出されるとき、そのパラメータも呼び出しを開始したプロセスのスタックにプッシュされ、呼び出しが完了すると、関数の戻り値もスタックに格納されます。スタックの先入れ後出し機能により、スタックは通話シーンの保存/復元に特に便利です。この意味で、スタックは一時的なデータを保存および交換するメモリ領域と考えることができます。
上記のメモリ領域内のデータ セグメント、BSS
セグメント、およびヒープは通常、メモリ内に連続的に格納され、位置も連続していますが、コード セグメントとスタックは独立して格納されることがよくあります。ストレージ。 i386
アーキテクチャでは、スタックは下方向に拡張され、ヒープは上方向に拡張され、互いに逆になります。
Linux で size
コマンドを使用して、コンパイルされたプログラムの各メモリ領域のサイズを確認することもできます。
リーリー
x86 32 ビット システムでは、Linux カーネル アドレス空間は、仮想アドレスが
0xC0000000 で始まり
で終わるハイエンド メモリ アドレス空間を指します。 0xFFFFFFFF、合計
1G の容量には、カーネル空間で実行されるカーネル イメージ、物理ページ テーブル、ドライバーなどが含まれます。
ダイレクト メモリ領域: カーネル空間の開始アドレスから始まり、カーネル空間の最大アドレス範囲
896M がダイレクト メモリ マッピング領域です。
ダイレクトマッピング領域の896MBの「リニアアドレス」は、「物理アドレス」の先頭の896MB
に直接マッピングされており、リニアアドレスと割り当てられた物理アドレスは連続しています。カーネルアドレス空間のリニアアドレス 0xC0000001
に対応する物理アドレスは 0x00000001
であり、それらの差はオフセット PAGE_OFFSET = 0xC0000000
この領域では、リニア アドレスと物理アドレスの間には線形変換関係があります。「リニア アドレス = PAGE_OFFSET
物理アドレス」。 virt_to_phys()
関数を使用して、次のこともできます。カーネル仮想空間のリニアアドレスを物理アドレスに変換します。
カーネル空間のリニア アドレス範囲は 896M ~ 1G で、容量 128MB のアドレス範囲はハイエンド メモリのリニア アドレス空間ですが、なぜハイエンド メモリのリニア アドレス空間と呼ばれるのでしょうか?説明しましょう:
前述したように、カーネル空間の合計サイズは 1GB であり、カーネル空間の開始アドレスから始まる 896MB のリニア アドレスは、物理アドレス サイズ 896MB のアドレス範囲に直接マッピングできます。
一歩下がって考えると、カーネル空間の 1 GB のリニア アドレスが物理アドレスにマップされている場合でも、最大 1 GB の物理メモリ アドレス範囲しかアドレス指定できません。
あなたが今持っているメモリースティックの大きさはどれくらいですか?目覚めてください。もうすぐ 2023 年です。ほとんどの PC のメモリは 1GB を超えています。
したがって、カーネル空間は最後の 128M アドレス範囲を取り出し、それを次の 3 つのハイエンド メモリ マッピング領域に分割して、物理アドレス範囲全体に対応します。 64 ビット システムでは、利用可能なリニア アドレス空間がインストール可能なメモリよりもはるかに大きいため、この問題は発生しません。
vmalloc 領域
カーネル関数 vmalloc
によって割り当てられる領域であり、その特徴は、線形空間は連続しているが、対応する物理アドレス空間は必ずしも連続しているわけではないことである。 vmalloc
割り当てられたリニア アドレスに対応する物理ページは、ローエンド メモリまたはハイエンド メモリに存在する可能性があります。
永続カーネル マッピング領域
この領域はハイエンド メモリにアクセスできます。アクセス方法は、alloc_page (_GFP_HIGHMEM)
を使用してハイエンド メモリ ページを割り当てるか、kmap
関数を使用して割り当てられたハイエンド メモリをこの領域にマップします。
カーネル マッピング領域の修正
この領域と 4G の上部には 4K 分離ゾーンのみがあり、その各アドレス エントリは ACPI_BASE
などの特定の目的を果たします。 。
カーネル空間の物理メモリ マッピング
######レビュー######メモリデータ構造
のメモリ管理オブジェクトに抽象化することです。
vm_area_struct
は、プロセスのアドレス空間を記述する基本的な管理単位です。プロセスは、ユーザー空間の仮想アドレスを記述するために複数の
を必要とすることがよくあります。「リンク リスト」を使用する必要があります。各 vm_area_struct
を整理するための「レッド リスト「ブラック ツリー」」。
リンク リストはすべてのノードを走査する必要がある場合に使用されますが、赤黒ツリーはアドレス空間内の特定のメモリ領域を見つけるのに適しています。カーネルは、メモリ領域でのさまざまな操作で高いパフォーマンスを実現するために両方のデータ構造を使用します。
ユーザー空間プロセスのアドレス管理モデル:
カーネル空間の章で「動的メモリマッピング領域」について説明しました。この領域はカーネル関数 vmalloc
によって割り当てられます。その特徴は、線形空間は連続していますが、対応する物理アドレスは次のとおりです。空間は必ずしも連続しているわけではありません。 vmalloc
割り当てられたリニア アドレスに対応する物理ページは、ローエンド メモリまたはハイエンド メモリに存在する可能性があります。
vmalloc
割り当てられるアドレスは、vmalloc_start
と vmalloc_end
の間に制限されます。割り当てられた各 vmalloc
カーネル仮想メモリは、vm_struct
構造に対応しており、異なるカーネル空間仮想アドレス間には、4k
サイズのアンチクロスボーダー空き領域間隔があります。地区。
ユーザー空間の仮想アドレス特性と同様に、これらの仮想アドレスには物理メモリとの単純なマッピング関係がありません。カーネル ページ テーブルを通じて物理アドレスまたは物理ページに変換する必要があります。まだマッピングされていない可能性があります。ページフォールトが発生した場合、物理ページが実際に割り当てられるのはその時だけです。
動的メモリマッピング
######結論は######この記事は、索引のような学習ガイドとして使用できます。特定の点を深く学習したい場合は、これらの章の入り口点と、メモリ管理の巨視的な視点でのこの知識点の位置を見つけることができます。 。
古いルールです、読んでいただきありがとうございます。記事の目的は知識の理解を共有することです。技術的な記事については、可能な限り正確性を保証するために繰り返し検証します。記事に明らかな欠陥がある場合は、 , ご指摘いただければ幸いです。一緒に議論します。勉強してください。本日のテクノロジー共有はここまでです。また次号でお会いしましょう。
以上がLinux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。