ホームページ  >  記事  >  システムチュートリアル  >  Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。

WBOY
WBOY転載
2024-02-10 23:48:03667ブラウズ

今日は Linux のメモリ管理について勉強します。

CURD に精通しているビジネス学生にとって、メモリ管理は遠い存在のように思えます。しかし、この知識点はあまり人気がありませんが(学習してもまったく使用しない人が多いと推測されます)、基本中の基礎であることは間違いありません。

これは武侠小説に登場する体内筋力トレーニングのようなもので、学んですぐに効果が現れるわけではありませんが、背筋が伸びるため、今後の開発に大いに役立ちます。

記事内のサンプル画像はすべて私が描いたものです。絵を描くのはコーディングよりも時間がかかりますが、言葉よりも絵を見たほうが誰でも直感的に理解できるので、今でも描いています。高解像度のサンプル写真が必要な学生向けに、記事の最後に入手方法があります。

より実用的な言い方をすると、面接中にうっかりこの知識を知っていることを明らかにし、1 つ、2 つ、3 つを話すことができれば、面接官はあなたにさらに興味を持ち、合格する可能性が高くなります。昇進、昇給、仕事など、人生の頂点に一歩近づきます。

前提条件: この記事の技術的な内容について説明する前提は、オペレーティング システム環境が

x86 アーキテクチャの 32 ビット Linux システムであることです。

仮想アドレス

最新のオペレーティング システムでも、メモリは依然としてコンピュータの非常に貴重なリソースです。コンピューターに搭載されているソリッド ステート ドライブが何テラバイトであるかを調べてから、メモリ サイズを調べてください。

システム メモリ リソースを最大限に活用および管理するために、Linux は仮想メモリ管理テクノロジを使用します。仮想メモリ技術を使用することで、各プロセスは相互に干渉しない 4GB の仮想アドレス空間を持ちます。

プロセスの初期化の割り当てと操作は、この「仮想アドレス」に基づいて行われます。プロセスが実際にメモリ リソースにアクセスする必要がある場合にのみ、仮想アドレスと物理アドレスの間のマッピングが確立され、物理メモリ ページが転送されます。

不適切なたとえで言えば、この原理は実際には現在の XX ネットワーク ディスクと同じです。ネットワーク ディスク容量が 1TB の場合、一度にそのような大きな容量が与えられると本当に思いますか?それはまだ若すぎます。スペースは、物を入れたときにのみ割り当てられ、入れた分だけ実際のスペースが割り当てられます。しかし、あなたとあなたの友人は両方とも 1TB のスペースを持っているようです。

仮想アドレスの利点

    ユーザーが物理メモリ アドレスに直接アクセスできないようにし、破壊的な操作を防止して、オペレーティング システムを保護します。
  • 各プロセスには 4GB の仮想メモリが割り当てられるため、ユーザー プログラムは実際の物理メモリよりも大きなアドレス空間を使用できます。
4GB プロセスの仮想アドレス空間は、「ユーザー空間」と「カーネル空間」の 2 つの部分に分かれています。

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。ユーザー空間カーネル空間

######実在住所######

ユーザー空間であろうとカーネル空間であろうと、使用されるアドレスは仮想アドレスであることは、上の章ですでにわかっています。プロセスが実際にメモリにアクセスする必要がある場合、カーネルの "リクエストページングメカニズム」を物理メモリページに転送します。

仮想アドレスをメモリの物理アドレスに変換します。これには、MMU

メモリ管理ユニット (メモリ管理ユニット) を使用して仮想アドレスをセグメント化し、ページ (セグメント ページ) アドレスを変換します。セグメンテーション ページングとページングの具体的なプロセスについてはここでは説明しませんので、コンピュータ構成原理の教科書を参照して説明してください。

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。

セグメントページメモリ管理アドレス変換

Linux カーネルは物理メモリを次の 3 つの管理領域に分割します。

ZONE_DMA

DMAメモリ領域。 0MB ~ 16MB のメモリ ページ フレームが含まれます。これは、DMA を介して古い ISA ベースのデバイスで使用でき、カーネルのアドレス空間に直接マップされます。

ZONE_NORMAL

通常のメモリ領域。カーネルのアドレス空間に直接マッピングされた、16MB ~ 896MB のメモリ ページ フレーム、通常のページ フレームが含まれます。

ZONE_HIGHMEM

ハイエンドのメモリ領域。直接マップされていない 896MB を超えるメモリ ページ フレームが含まれています。メモリ ページ フレームのこの部分には、永続マッピングおよび一時マッピングを通じてアクセスできます。

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。物理メモリ領域の分割

ユーザースペース

ユーザープロセスがアクセスできるのは「ユーザー空間」です。各プロセスは独自の独立したユーザー空間を持っています。仮想アドレス範囲は

0x00000000 から 0xBFFFFFFF で、総容量は 3G です。 。

ユーザー プロセスは通常、ユーザー空間の仮想アドレスにのみアクセスでき、インライン操作またはシステム コールを実行する場合にのみカーネル空間にアクセスできます。

プロセスとメモリ

プロセス(実行プログラム)が占有するユーザー空間は、「アクセス属性が一致したアドレス空間をまとめて格納する」という原理により、

5の異なるメモリ領域に分割されます。アクセス属性とは、「読み取り可能、書き込み可能、​​実行可能など」を指します。

    ###コードスニペット###
  • コードセグメントは、実行可能ファイルの操作命令と実行可能プログラムのイメージをメモリに格納するために使用されます。コード セグメントは実行時に不正な変更から保護する必要があるため、読み取り操作のみが許可され、書き込みはできません。

    データセグメント
  • データセグメントは、実行ファイル内で初期化されたグローバル変数、つまりプログラムによって静的に割り当てられた変数やグローバル変数を格納するために使用されます。

    BSSセグメント
  • プログラム内の
  • BSS

    セクションには初期化されていないグローバル変数が含まれており、メモリ内のすべての

    bss セクションは 0 に設定されます。

    ヒープ
  • ヒープ
  • ヒープは、プロセス操作中に動的に割り当てられるメモリ セグメントを格納するために使用されます。そのサイズは固定されておらず、動的に拡張または縮小できます。プロセスが malloc などの関数を呼び出してメモリを割り当てると、新しく割り当てられたメモリがヒープに動的に追加されます (ヒープが拡張されます)。free などの関数を使用してメモリを解放すると、解放されたメモリがヒープから削除されます。 (ヒープが削減されます)。

  • スタック スタック

    スタックは、プログラムを保存するためにユーザーによって一時的に作成されるローカル変数、つまり関数で定義された変数です (ただし、static で宣言された変数は含まれません。静的とは、変数をスタックに保存することを意味します)データセグメント)。さらに、関数が呼び出されるとき、そのパラメータも呼び出しを開始したプロセスのスタックにプッシュされ、呼び出しが完了すると、関数の戻り値もスタックに格納されます。スタックの先入れ後出し機能により、スタックは通話シーンの保存/復元に特に便利です。この意味で、スタックは一時的なデータを保存および交換するメモリ領域と考えることができます。

上記のメモリ領域内のデータ セグメント、BSS セグメント、およびヒープは通常、メモリ内に連続的に格納され、位置も連続していますが、コード セグメントとスタックは独立して格納されることがよくあります。ストレージ。 i386 アーキテクチャでは、スタックは下方向に拡張され、ヒープは上方向に拡張され、互いに逆になります。 Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。

Linux で size コマンドを使用して、コンパイルされたプログラムの各メモリ領域のサイズを確認することもできます。 リーリー

カーネルスペース

x86 32 ビット システムでは、Linux カーネル アドレス空間は、仮想アドレスが 0xC0000000 で始まり で終わるハイエンド メモリ アドレス空間を指します。 0xFFFFFFFF、合計 1G の容量には、カーネル空間で実行されるカーネル イメージ、物理ページ テーブル、ドライバーなどが含まれます。

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。カーネル空間サブディビジョン領域。

ダイレクトマッピングエリア

ダイレクト マッピング領域

ダイレクト メモリ領域: カーネル空間の開始アドレスから始まり、カーネル空間の最大アドレス範囲 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 などの特定の目的を果たします。 。

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。

カーネル空間の物理メモリ マッピング

######レビュー######

上記では話すべきことがたくさんあるので、急いで次のセクションに進まないでください。その前に、上で述べたことを復習しましょう。上記の章を注意深く読むと、ここで別の図を描きました。メモリ管理の全体像が頭の中にあるはずです。

カーネル空間とユーザー空間の全体像

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。メモリデータ構造

カーネルがシステム内の仮想メモリを管理するには、カーネルからメモリ管理データ構造を抽象化する必要があります。「割り当て、解放など」などのメモリ管理操作は、これらのデータ構造操作に基づいています。 2 つのデータ管理仮想メモリ領域の構造。

ユーザー空間メモリのデータ構造

前の章「プロセスとメモリ」では、Linux プロセスが 5 つの異なるメモリ領域、つまりコード セグメント、データ セグメント、BSS、ヒープ、スタック、カーネル管理に分割できると述べました。これらの領域の方法は、これらのメモリ領域を

vm_area_struct

のメモリ管理オブジェクトに抽象化することです。 vm_area_struct は、プロセスのアドレス空間を記述する基本的な管理単位です。プロセスは、ユーザー空間の仮想アドレスを記述するために複数の

vm_area_struct

を必要とすることがよくあります。「リンク リスト」を使用する必要があります。各 vm_area_struct を整理するための「レッド リスト「ブラック ツリー」」。 リンク リストはすべてのノードを走査する必要がある場合に使用されますが、赤黒ツリーはアドレス空間内の特定のメモリ領域を見つけるのに適しています。カーネルは、メモリ領域でのさまざまな操作で高いパフォーマンスを実現するために両方のデータ構造を使用します。 ユーザー空間プロセスのアドレス管理モデル:

wm_arem_struct

カーネル空間はメモリ データ構造を動的に割り当てます

カーネル空間の章で「動的メモリマッピング領域」について説明しました。この領域はカーネル関数 vmalloc によって割り当てられます。その特徴は、線形空間は連続していますが、対応する物理アドレスは次のとおりです。空間は必ずしも連続しているわけではありません。 vmalloc 割り当てられたリニア アドレスに対応する物理ページは、ローエンド メモリまたはハイエンド メモリに存在する可能性があります。

vmalloc 割り当てられるアドレスは、vmalloc_startvmalloc_end の間に制限されます。割り当てられた各 vmalloc カーネル仮想メモリは、vm_struct 構造に対応しており、異なるカーネル空間仮想アドレス間には、4k サイズのアンチクロスボーダー空き領域間隔があります。地区。

ユーザー空間の仮想アドレス特性と同様に、これらの仮想アドレスには物理メモリとの単純なマッピング関係がありません。カーネル ページ テーブルを通じて物理アドレスまたは物理ページに変換する必要があります。まだマッピングされていない可能性があります。ページフォールトが発生した場合、物理ページが実際に割り当てられるのはその時だけです。

Linux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。

動的メモリマッピング

######結論は######

Linuxメモリ管理は非常に複雑なシステムです。この記事で説明されているのは氷山の一角です。マクロの観点からメモリ管理の全体像を示しますが、一般的に言えば, この知識は、面接官とチャットするときに重要になります。読書するときにも役に立ちます。もちろん、読書を通じて皆さんもより深い原則を理解できることを願っています。

この記事は、索引のような学習ガイドとして使用できます。特定の点を深く学習したい場合は、これらの章の入り口点と、メモリ管理の巨視的な視点でのこの知識点の位置を見つけることができます。 。

この記事を作成するにあたり、知識のインデックスとして使用できる図例も多数描きました。個人的には、文章を読むよりも画像で見た方がわかりやすいと感じます。私の公式アカウント「バックエンドテクノロジースクール」の背景「メモリ管理」の高解像度のオリジナル画像を取得します。

古いルールです、読んでいただきありがとうございます。記事の目的は知識の理解を共有することです。技術的な記事については、可能な限り正確性を保証するために繰り返し検証します。記事に明らかな欠陥がある場合は、 , ご指摘いただければ幸いです。一緒に議論します。勉強してください。本日のテクノロジー共有はここまでです。また次号でお会いしましょう。

以上がLinux のメモリ管理が理解できないと言うのはやめてください。10 枚の図を見れば一目瞭然です。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlxlinux.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。