Linuxカーネル-プロセスアドレス空間

この記事は以下から借用しています:https://www.cnblogs.com/fengliu-/p/9243004.html
https://blog.csdn.net/wsq119/article/details/82110757
https://www.cnblogs.com/ wuchanming / p / 4339770.html

プロセスアドレス空間分布図:
ここに画像の説明を挿入
プログラムセグメント(テキスト):メモリ内のプログラムコードのマッピング。関数本体のバイナリコードを格納します。
初期化データ(データ):プログラム開始時に変数に初期化されたデータ。
初期化されていないデータ(BSS):プログラム操作の開始時に変数を初期化していないデータ。
スタック:ローカル変数と一時変数を格納します。関数が呼び出されると、関数の戻りポインターが格納されます。このポインターは、関数の呼び出しと戻りを制御するために使用されます。メモリはプログラムブロックの最初に自動的に割り当てられ、メモリは最後に自動的に解放されます。動作モードはデータ構造のスタックに似ています。
ヒープ:ストレージの動的メモリ割り当て。プログラマーによる手動割り当てと手動解放が必要です。データ構造のヒープとは異なり、割り当て方法はリンクリストに似ていることに注意してください。

初期のメモリ割り当てメカニズム

初期のコンピュータでは、プログラムを実行するために、これらすべてのプログラムがメモリにロードされ、プログラムはメモリ上で直接実行されました。つまり、プログラムでアクセスされるメモリアドレスは、実際の物理メモリアドレスでした。コンピュータが複数のプログラムを同時に実行する場合、これらのプログラムによって使用されるメモリの合計量が、コンピュータの実際の物理メモリのサイズよりも少ないことを確認する必要があります。
プログラムが複数のプログラムを同時に実行する場合、オペレーティングシステムはこれらのプログラムにどのようにメモリを割り当てますか?以下は、当時のメモリ割り当て方法を説明する例
です。コンピュータの合計メモリサイズは128Mで、2つのプログラムAとBが同時に実行され、Aは10Mのメモリを占有する必要があり、Bは必要です。 110のメモリを占有します。コンピュータがプログラムにメモリを割り当てるとき、この方法を採用します。最初にメモリの最初の10MをプログラムAに割り当て、次にメモリの残りの118Mから110Mを除算してプログラムBに割り当てます。この割り当て方法により、プログラムAとプログラムBの両方を確実に実行できますが、この単純なメモリ割り当て戦略には多くの問題があります。

セグメント化

上記の問題を解決するために、人々は回避策を考えました。それは、中間層を追加し、間接アドレスアクセス方式を使用して物理メモリにアクセスすることです。この方法によれば、プログラムでアクセスされるメモリアドレスは、実際の物理メモリアドレスではなく仮想アドレスであり、オペレーティングシステムはこの仮想アドレスを適切な物理メモリアドレスにマップします。このように、オペレーティングシステムが仮想アドレスから物理メモリアドレスへのマッピングを処理する限り、異なるプログラムによって最終的にアクセスされるメモリアドレスが互いに重複することなく異なる領域に配置され、メモリアドレス空間の効果を保証できます。分離を実現できます。
プロセスが作成されると、オペレーティングシステムはプロセスに4GBの仮想プロセスアドレス空間を割り当てます。4GBである理由は、32ビットオペレーティングシステムでは、ポインターの長さが4バイトであり、4バイトポインターのアドレス指定機能が0x00000000から0xFFFFFFFFであり、最大値0xFFFFFFFFが4GBの容量を表すためです。 。仮想アドレス空間とは対照的に、実際の物理メモリに対応する物理アドレス空間もあります。コンピュータに512Mのメモリがインストールされている場合、この物理アドレス空間の範囲は0x00000000〜0x1FFFFFFFです。オペレーティングシステムが仮想アドレスを物理アドレスにマップする場合、この範囲にのみマップでき、オペレーティングシステムはこの範囲にのみマップできます。プロセスが作成されると、各プロセスには独自の4GB仮想アドレス空間があります。この4GBのアドレス空間は「仮想」であり、実在ではなく、各プロセスは独自の仮想アドレス空間のデータにのみアクセスでき、他のプロセスのデータにはアクセスできないことに注意してください。これは、この方法によって実現されます。プロセス間のアドレス分離。
人々が仮想アドレス空間を作成したい理由は、プロセスアドレス空間の分離の問題を解決するためです。ただし、プログラムを実行する場合は、実メモリ上で実行する必要があるため、仮想アドレスと物理アドレスの間にマッピング関係を確立する必要があります。このように、マッピングメカニズムを介して、プログラムが仮想アドレス空間のアドレス値にアクセスする場合、それは物理アドレス空間の別の値にアクセスすることと同じです。人々はセグメンテーションの方法を考えます。そのアイデアは、仮想アドレス空間と物理アドレス空間の間で1対1のマッピングを行うことです。たとえば、仮想アドレス空間の10Mのスペースは、物理アドレス空間の10Mのスペースにマップされます。この考え方を理解するのは難しくありません。オペレーティングシステムは、さまざまなプロセスのアドレス空間が物理アドレス空間のさまざまな領域にマップされ、各プロセスが最終的にアクセスできるようにします。
物理アドレス空間は互いに分離されています。このようにして、プロセス間のアドレス分離が実現されます。説明のために例を見てみましょう。2つのプロセスAとBがあるとします。プロセスAのメモリサイズは10M、仮想アドレス空間は0x00000000から0x00A00000に分散され、プロセスBに必要なメモリは100M、仮想アドレス空間は0x00000000から0x06400000まで配布されます。次に、セグメント化されたマッピング方法に従って、プロセスAは物理メモリ上の領域を0x00100000から0x00B00000にマッピングし、プロセスBは物理メモリ上の領域を0x00C00000から0x07000000にマッピングします。したがって、プロセスAとプロセスBはそれぞれ異なるメモリ範囲にマッピングされ、互いにオーバーラップせず、アドレスの分離を実現します。アプリケーションプログラムの観点から、プロセスAのアドレス空間は0x00000000から0x00A00000まで分散されます。開発中、開発者はこの範囲のアドレスにアクセスするだけで済みます。アプリケーションプログラムは、プロセスAが物理メモリの領域にマップされていることを気にしないため、プログラムの実行アドレスは決定されるのと同じです。
このセグメント化されたマッピング方法は、上記の1番目と3番目の問題を解決しますが、2番目の問題、つまりメモリ使用効率の問題は解決しません。セグメント化されたマッピング方法では、メモリがスワップインおよびスワップアウトされるたびにプログラム全体が実行されるため、多数のディスクアクセス操作が発生し、効率が低下します。したがって、このマッピング方法はまだ少し粗く、粒度は比較的大きくなります。実際、プログラムの操作には局所性の特徴があり、一定期間、プログラムはプログラムのデータのごく一部にしかアクセスしません。つまり、プログラムのデータのほとんどはで使用されません。一定期間。この状況に基づいて、人々はより小さな粒度でメモリのセグメンテーションとマッピングの方法を考えます。この方法はページングです。

ページネーション

ページングの基本的な方法は、アドレス空間を多くのページに分割することです。各ページのサイズはCPUによって決定され、オペレーティングシステムがページサイズを選択します。現在、InterシリーズのCPUは4KBまたは4MBのページサイズをサポートしていますが、PCは現在4KBを使用することを選択しています。この選択によれば、4GBの仮想アドレス空間は1048576ページに分割でき、512Mの物理メモリは131072ページに分割できます。明らかに、仮想空間のページ数は、物理空間のページ数よりもはるかに多くなります。
セグメンテーション方式では、プログラムを実行するたびにプログラムが常にメモリにロードされますが、ページング方式は異なります。ページングのアイデアは、プログラムの実行時にページが使用されるメモリを割り当てることであり、未使用のページは一時的にハードディスクに保持されます。これらのページが使用されると、物理アドレス空間内のこれらのページにメモリが割り当てられ、仮想アドレス空間内のページと新しく割り当てられた物理メモリページとの間のマッピングが確立されます。
以下では、実行可能ファイルのロードプロセスを導入することによるページングメカニズムの実装について説明します。実行可能ファイル(PEファイル)は、実際にはコンパイルおよびリンクされたデータと命令のコレクションであり、多くのページに分割されます。PEファイルの実行中に、メモリにロードされる単位はページです。PEファイルが実行されると、オペレーティングシステムは最初にプログラム用に4GBのプロセス仮想アドレス空間を作成します。前述のように、仮想アドレス空間は単なる中間層であり、その機能はマッピングメカニズムを使用して仮想アドレス空間を物理アドレス空間にマッピングすることです。したがって、4GBの仮想アドレス空間を作成することは実際には空間を作成することではなく、そのマッピングメカニズムを作成するために必要なデータ構造は、ページヘッダーとページテーブルのデータ構造にすぎません。
仮想アドレス空間に必要なデータ構造を作成した後、プロセスはPEファイルの最初のページの読み取りを開始します。PEファイルの最初のページには、PEファイルヘッダーやセグメントテーブルなどの情報が含まれています。ファイルヘッダーとセグメントテーブルに従って、プロセスはPEファイル内のすべてのセグメントを仮想アドレス空間内の対応するページにマップします( PEファイル)。セグメントの長さはページ長の整数倍です)。現時点では、PEファイルの実際の命令とデータはメモリにロードされていません。オペレーティングシステムは、ヘッダーやその他の情報に従って、PEファイルとプロセス仮想アドレス空間のページとの間のマッピング関係を確立するだけです。 PEファイル。CPUがプログラムで使用されている特定の仮想アドレスにアクセスする場合、そのアドレスに物理アドレスが関連付けられていないことをCPUが検出すると、CPUは仮想アドレスが配置されているページを空のページと見なし、CPUはこれはページフォールト(ページフォールト)であり、CPUはオペレーティングシステムがPEページにメモリを割り当てていないことも認識し、CPUはオペレーティングシステムに制御を戻します。次に、オペレーティングシステムは、PEページの物理空間にページを割り当て、物理ページを仮想空間の仮想ページにマップしてから、制御をプロセスに戻し、プロセスはページが配置された位置から再開します。障害が発生しました。実行されました。この時点でPEファイルのそのページにメモリが割り当てられているため、ページフォールトは発生しません。プログラムの実行に伴い、ページフォールトが引き続き発生し、オペレーティングシステムは、プロセスのニーズを満たすために、対応する物理ページをプロセスに割り当てます。
ページング方式の中心的な考え方は、実行可能ファイルがx番目のページに実行されると、メモリページyがx番目のページに割り当てられ、このメモリページがプロセス仮想アドレス空間のマッピングテーブルに追加されることです。 。このマッピングテーブルは、y = f(x)関数では同等です。アプリケーションは、このマッピングテーブルを介してxページに関連付けられたyページにアクセスできます。
以上のことから、プロセス作成の過程で、プログラムのすべてのコンテンツは、プロセスの仮想メモリ空​​間にマップされます。限られた物理メモリ空間で大きなプログラムを実行できるようにするために、プログラムの最初の部分を物理メモリ空間にロードして実行できます。これは、オペレーティングシステムがプロセスを処理するためです。仮想アドレスから物理アドレスへの変換プロジェクトに物理アドレスが存在しない場合は、この時点でページ障害(nopage)が発生し、オペレーティングシステムがロードします。メモリにロードされていないディスクデータが物理メモリにロードされ、対応するプロセスページテーブルが更新されます。この時点で物理メモリがいっぱいの場合、オペレーティングシステムは何をしますか?
Linuxオペレーティングシステムがそれをどのように処理するかを見てみましょう
プロセスが仮想ページを物理メモリにロードしたいが、そこにある場合使用可能なページはありません。空き物理ページがある場合、オペレーティングシステムは、このページ用のスペースを確保するために、物理メモリ内の他のページを削除する必要があります。
Linuxオペレーティングシステムでは、物理ページの説明は次のとおりです。

struct mem_map
{
    
    
1、本页使用计数,当该页被许多进程共享时计数将大于1
2、age描叙本页的年龄,用来判断该页是否为淘汰或交换的好候选
3、map_nr描叙物理页的页帧号
}

物理メモリから削除されたページがイメージまたはデータファイルからのものであり、書き込まれていない場合、ページを保存する必要はなく、破棄できます。プロセスがページを必要とする場合、メモリ内の画像またはデータファイルからページを取得できます。
ただし、ページが変更されている場合、後でアクセスできるように、オペレーティングシステムはページのコンテンツを保持する必要があります。この種のページは「ダーティページ」と呼ばれ、メモリから削除されると、スワップファイルと呼ばれる特別なファイルに保存されます。
プロセッサと物理メモリの速度に比べて、スワップファイルへのアクセスには長い時間がかかり、オペレーティングシステムは、ディスクへのページの書き込みと、ページが再び使用されるときのメモリの取得の問題に多くの時間を費やす必要があります。
どのページが削除または交換されるかを決定するために使用されるアルゴリズムが十分に効率的でない場合、「ジッター」と呼ばれる状況が発生する可能性があります。この場合、ページは常にディスクに書き込まれて読み戻され、オペレーティングシステムはビジー状態で実際の作業を実行できません。
Linuxは、「最近使用されていない(LRU)」ページング手法を使用して、システムから削除できるページを適切に選択します。このデザインシステムの各ページには「年齢」があり、ページにアクセスすると年齢が変化します。ページにアクセスする回数が多いほど、ページは若くなり、訪問数が少ないほど、ページは古くなります。古いページは交換に最適な候補ページです。

Linux仮想ストレージ組織

各プロセス(スレッド)はプロセス記述子(task_struct)に対応し、各プロセス記述子には一意のプロセスアドレス空間であるメモリ記述子(mm_struct)があり、メモリ記述子には仮想メモリ領域のリンクリスト(vm_area_struct)が含まれています。アドレス空間で使用される領域
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/chengcheng1024/article/details/114382951