Linuxのメモリ管理についてそれらのことについて話す

Linux関連のビデオ分析:

Linuxカーネルのアーキテクチャを5つの側面で分析し、カーネルに慣れいないようにします
。Linuxカーネルファイルシステムを実装する方法を説明します。

1はじめに

メモリ管理はLinuxカーネルの非常に重要な部分です。今日はそれを一緒に学びましょう。

新しい知識ポイントを学びたいとき、より良いプロセスは、最初にこのテクノロジーポイントの出現の背景理由、同時に他の解決策、新しいテクノロジーポイントが解決する問題、およびそれが持つ欠陥と改善点を理解することです。 、研究全体が閉ループになるように、個人的にはこれは良い学習アイデアだと思います。

すべてが相互に関連しており、コンピュータサイエンスのいくつかの問題は実際の生活でプロトタイプ化できるため、ほとんどのコンピュータサイエンティストは、生命を観察して要約するのが得意だと思います。人間社会はメカニズムとルールに満ちた複雑なマシンであるため、最初に生き返り、プロトタイプを探してからコードを探索するよりも、コードの海に飛び込んだほうがよい場合があります。

Linuxのメモリ管理ボリュームは多数あり、この記事では、氷山の概要を段階的に紹介することしかできません。この記事を通じて、次のことを学びます。

  • なぜメモリを管理する必要があるのですか
  • Linuxセグメントページ管理メカニズム
  • メモリの断片化のメカニズム
  • バディシステムの基本原則
  • バディシステムの長所と短所
  • スラブディストリビューターの基本原理

2メモリを管理する必要がある理由

老子の有名な見方は、何もしないことで支配することです。簡単に言えば、あまり介入せず、自己意識に頼ることなく、秩序正しく運営することができます。理想は美しく、現実は残酷です。

Linuxシステムで基本的かつ単純な方法でメモリを管理することにはいくつかの問題があります。いくつかのシナリオを見てみましょう。

2.1メモリ管理の問題

プロセススペースの分離の問題

Linuxのメモリ空間で3つのプロセスABCが実行されている場合は、以下に示すように、osによって割り当てられたアドレス空間をプロセスAに0〜20M、プロセスBのアドレス空間を30〜80M、プロセスCのアドレス空間を90〜120Mに設定します。図:
ここに画像の説明を挿入

プロセスAがプロセスBに属するスペースにアクセスし、プロセスBがプロセスCに属するスペースにアクセスし、さらにはスペースの値を変更するなど、特定の時間にプログラムスペースへのアクセスに問題が発生する可能性があります。これにより混乱が生じます。とエラー、したがって実際の中国はこれが起こることを許可していません。

メモリ効率とメモリ不足の問題
マシンのメモリは限られたリソースであり、プロセスの数を特定できません。ある時点で開始されたプロセスがすべてのメモリスペースを占有している場合、この時点では新しいプロセスを開始できません。使用可能な新しいメモリはありません。割り当てられていますが、開始されたプロセスがスリープ状態になることがあります。つまり、メモリが使用されていないため、効率が少し低いため、管理者が未使用のメモリを空にする必要があります。連続メモリそれは本当に貴重です。多くの場合、連続したメモリを効率的かつ時間内に割り当てることができないため、仮想化と離散化によってメモリ使用量が効果的に増加する可能性があります。

プログラムの配置、デバッグ、コンパイル、および実行の問題。
プログラムの実行中はプログラムの位置が不確実であるため、問題の特定、コードのデバッグ、コンパイルと実行で多くの問題が発生します。各プロセスに一貫性のある完全なアドレス空間。コンパイルおよび実行中のリンカーとローダーの使用を簡素化するために、ヒープ、スタック、コードセグメントなどが開始位置に配置されます。

2.2仮想アドレス空間
上記の問題のいくつかを解決するために、Linuxシステムは仮想空間の概念を導入します。仮想化の出現はハードウェアと密接に関連しています。これはソフトウェアとハ​​ードウェアの組み合わせの結果であると言えます。 。仮想アドレス空間はプログラムと物理空間にあります。追加された中間層はメモリ管理の焦点でもあります。

大容量ストレージとしてのディスクは、「メモリ」の一部としてプログラムの動作にも関与します。メモリ管理システムは、一般的に使用されていない非アクティブなメモリをページアウトします。メモリは、ディスクのキャッシュ、およびアクティブメモリが予約されています。仮想メモリと呼ばれ、物理メモリに関連する限られた物理メモリ空間を間接的に拡張するデータ。
ここに画像の説明を挿入
[記事のメリット] C / C ++ Linuxサーバーアーキテクトの学習資料とグループ812855908(C / C ++、Linux、golangテクノロジー、Nginx、ZeroMQ、MySQL、Redis、fastdfs、MongoDB、ZK、ストリーミングメディア、CDN、P2P、K8S、 Docker、TCP / IP、coroutine、DPDK、ffmpegなど)
ここに画像の説明を挿入

3.セグメントページ管理メカニズム

これらの詳細に関する優れた記事がたくさんあり、興味のある人はワンクリックで検索エンジンを使用してそれらに到達できるため、この記事はセグメント管理メモリとページング管理メモリには入りません。

セグメントページメカニズムは一夜にして実現されるものではなく、純粋な物理セグメンテーション、純粋なページング、純粋な論理セグメンテーションの段階を経て、最終的にセグメンテーションとページングを組み合わせたメモリ管理方法を進化させました。セグメントページの組み合わせには、次の利点があります。セグメンテーションとページング。また、単一モデルの欠点を回避し、より優れた管理モデルです。

この記事では、段落管理メカニズムに関する一般的な概念についてのみ説明します。段落管理メカニズムは、セグメント管理とページング管理を組み合わせたものです。セグメント管理は論理的な管理方法であり、ページング管理は物理的な管理方法です。

コンピュータのいくつかの技術と実装は、実生活で見つけることができます。いわゆる芸術と技術は、おそらくこれを意味します。

栗を取る:
住民の戸籍の管理には、地区、郡、市の概念がありますが、実際にはそのようなエンティティはありません。論理的です。これらの行政単位を追加すると、住所管理がより直接的になります。

私たちの住人にとって、唯一の存在は自分の家と住居であり、これは物理的な単位であり、現実の存在であり、最も基本的な単位でもあります。

Linuxセグメントページの管理と比較すると、セグメントは地区、郡、都市の概念に相当する論理単位であり、ページはコミュニティ/家の概念に相当する物理単位であり、はるかに便利です。

マルチレベルのページテーブルも理解しやすいです。合計物理メモリが4GBでページサイズが4KBの場合、合計2 ^ 20ページになりますが、それでも非常に大きくなります。次の方法でインデックスアドレスを作成するのは不便です。番号付けなので、マルチレベルのページテーブルを導入して、ストレージを減らし、管理を容易にします。

セグメントページメカニズムによってサポートされる論理アドレスと物理アドレスの間のマッピング関係、つまり、仮想アドレスと物理アドレスの間の対応する関係の簡略図。
ここに画像の説明を挿入

MMUメモリ管理ユニット(MMUメモリ管理ユニット)は、主に仮想アドレスから物理アドレスへのマッピングを提供するハードウェア層コンポーネントです。

MMUワークフロー:CPUが論理アドレスを生成してセグメンテーションユニットに配信し、セグメンテーションユニットが論理アドレスを線形アドレスに変換する処理を実行してから、線形アドレスがページングユニットに配信され、ページングユニットがページテーブルマッピングに従ってメモリの物理アドレスを変換します。ページ障害が中断される可能性があります。

ページフォールト割り込み(ページフォールト)は、ソフトウェアが仮想アドレスにアクセスしようとした場合にのみ発生します。セグメントページが物理アドレスに変換された後、この時点でページがメモリにないことが判明すると、CPUがレポートします。割り込みを実行してから相関を実行する例外が発生した場合、仮想メモリの転送または割り当てが直接中断されることがあります。

4.物理メモリとメモリの断片化

前述のセグメントページ管理メカニズムは仮想空間の一部ですが、Linuxメモリ管理のもう1つの重要な部分は、物理メモリの管理、つまり、物理メモリの割り当てと再利用の方法です。これには、いくつかのメモリ割り当てアルゴリズムとアロケータが含まれます。
ここに画像の説明を挿入

4.1物理メモリアロケータ

アロケータと割り当てアルゴリズムは会社の財務のようなものであり、メモリは会社の資金のようなものです。資金を合理的に使用する方法は財務の責任であり、物理メモリを合理的に使用する方法はアロケータの仕事です。
ここに画像の説明を挿入

4.2メモリの断片化の分類とメカニズム
メモリの断片化とは何かわからない場合は、よく言われる断片化された時間、つまりアイドル状態であるが使用されていない時間について考えてみてください。実際、メモリについても同じことが言えます。
ここに画像の説明を挿入

断片化された後は時間もメモリも効果的に使用できないため、断片化の合理的な管理と削減が重要であり、これは物理メモリ割り当てアルゴリズムとアロケータの焦点でもあります。

フラグメントの場所と原因に​​応じて、メモリフラグメントは外部フラグメントと内部フラグメントに分けられます。これら2つのフラグメントの視覚的表示を見てみましょう。
ここに画像の説明を挿入

図から、外部フラグメントはプロセス間で割り当てられていないメモリスペースであることがわかります。外部フラグメントの出現は、プロセスによるメモリの頻繁な割り当てと解放に直接関係しています。これはよく理解されています。異なるスペースを割り当てるプロセスの解放をシミュレートします。外部の破片の生成を見ることができます。

内部フラグメンテーションは、主にアロケータの粒度と、実際に割り当てられたメモリが必要なメモリよりも大きくなる原因となるいくつかのアドレス制限が原因であるため、プロセスにメモリホールが発生します。

仮想アドレスにより、プロセスで使用されるメモリが物理メモリ内で個別になりますが、多くの場合、プロセスには一定量の連続した物理メモリが必要です。フラグメントが多数存在すると、プロセスを開始できないという問題が発生します。 、Process7に示すように、継続的な物理メモリが必要ですが、割り当てることはできません。
ここに画像の説明を挿入

それでもはっきりしない場合は、通常、カフェテリアに行くか、3〜5人の友人とバスに乗るシーンを想像してみてください。車全体に3つの連続した座席がないため、別々に座るか、立っている必要があります。
ここに画像の説明を挿入

5.バディシステムアルゴリズムの基本原則

5.1いくつかの準備知識
物理ページフレーム
Linuxは物理メモリをページに分割します。メモリページのサイズはソフトウェアやハードウェアによって異なる場合があります。Linuxカーネルは4KBに設定されており、一部のカーネルは大きい場合と小さい場合がありますが、その時点では異なります。パンと同じように、サイズは常に実際に考慮されます。大小があり、均一ではありません。

ページフレームの記録構造
カーネルには、物理​​メモリページの使用状況の監視を確立するために、ページのロケーションアドレス/使用状況を記録するための構造体ページなどのデータ構造があります。カーネルによるメモリページの管理の説明に。

遅延割り当てとリアルタイム割り当て
Linuxシステムは、カーネルモードとユーザーモードに分けられます。メモリのカーネルモードアプリケーションはすぐに満たされ、要求は合理的でなければなりません。ただし、メモリのユーザーモード要求は、物理メモリを割り当てるために常に可能な限り遅延されるため、ユーザーモードプロセスは最初に仮想メモリ領域を取得し、実行時にページフォールト例外を介して実際の物理メモリの一部を取得します。 mallocを実行するとgetは、仮想メモリは実際の物理メモリに他なりません。これもこの理由によって発生します。

5.2バディシステムの紹介
このアルゴリズム名を初めて聞いたとき、なぜバディシステムと呼ばれるのか不思議に思います。一緒に秘密を明かしましょう。


バディシステムはどのような問題を解決しますか?バディシステムアルゴリズムは、外部フラグメントを解決するための強力なツールです。簡単に言えば、さまざまなサイズの連続ページフレームのグループがシナリオにリソースを効率的に割り当てて再利用するための一連の管理メカニズムを確立します。頻繁に要求され、リリースされます。外部の断片化を減らします。

外部フラグメント
解決する最初のアイデア:既存の外部フラグメントを新しいテクノロジーを介して連続線形空間にマッピングし、これらの非連続の空きメモリを連続線形空間にマッピングします。実際、外部の生成を減らすのではなく、ガバナンスソリューションと同等です。ただし、このスキームは、連続した物理メモリが実際に必要な場合には効果がありません。

2番目のアイデア:これらの小さな空きの不連続メモリを記録します。新しい割り当て要件がある場合は、割り当てに適した空きメモリを検索して、新しい領域にメモリが割り当てられないようにします。無駄を宝物として使用する感覚にはバリエーションがあります。ビスケットのパックを食べたいとき、あなたの母親は間違いなく、新しいビスケットを開くのではなく、残りの半分のビスケットを最初に食べるように言うでしょう。

他のいくつかの考慮事項に基づいて、Linuxカーネルは外部の断片化を解決するために2番目のアイデアを選択しました。

パートナーメモリブロックの定義
パートナーシステムでは、同じサイズで連続した物理アドレスを持つ2つのメモリ領域はパートナーと呼ばれます。連続アドレスの要件は実際にはより厳格ですが、このような2つのメモリがあるため、これはアルゴリズムの鍵でもあります。エリアは、より大きなエリアにマージできます。


バディシステムのコアアイデアバディシステムは、さまざまなサイズの連続した物理ページフレームを管理し、適用時に最も近いページフレームサイズから割り当て、残りを分解し、パートナーシップとメモリをラージページフレームにマージします。

5.3
バディシステムの基本プロセスバディシステムは、n = 0〜10の合計11個のブロックリンクリストを維持し、各ブロックリンクリストには2 ^ n個の連続した物理ページが含まれます。n = 10の場合、1024個の4KBページは4MBの連続する物理メモリブロックに対応します。ここで、nは順序と呼ばれます。パートナーシステムでは、順序は0〜10、つまり最小は4KB、最大のメモリブロックは4MBです。同じサイズのこれらの物理ブロックは、管理用の二重リンクリストを形成します。この図は、order = 0およびorder = 2の2つの二重リンクリストを示しています。
ここに画像の説明を挿入

メモリ適用プロセス:ページフレームブロックが要求されたと仮定すると、パートナーシステムアルゴリズムは最初に、order = 0のリンクリストに割り当てられる空きブロックがあるかどうかをチェックします。そうでない場合は、次に大きいブロックを検索し、order = 1のリンクリストで空きブロックを見つけ、リンクリストにある場合は2ページフレームを分割し、1ページフレームを割り当てて1ページフレームをorder = 0に追加します。リンクリスト。order = 1のリンクリストに空きブロックが見つからない場合は、より大きな注文を検索し続けます。分割用に見つかった場合、order = 10のリンクリストに空きブロックがない場合、アルゴリズムはエラーを報告します。

メモリをマージするプロセス:メモリをマージするプロセスは、パートナーアルゴリズムのパートナーブロックの実施形態です。アルゴリズムは、同じサイズAのメモリの2つのブロックと、それらの物理アドレスを2Aのサイズの単一のブロックにマージします。バディアルゴリズムはボトムアップで繰り返しマージされます。実際、このプロセスはleveldbのsstマージプロセスと非常に似ています。違いは、バディアルゴリズムではメモリブロックが連続している必要があることです。このプロセスは、パートナーの親しみやすさも反映しています。システムからメモリの大きなブロックへ。
ここに画像の説明を挿入

5.4
バディシステムの長所と短所バディシステムアルゴリズムは、外部フラグメンテーションの問題を解決し、大きなメモリブロックの割り当てに適しています。粒度の小さいメモリは内部フラグメンテーションを引き起こす可能性がありますが、バディシステムの定義は非常に厳密です。パートナーブロックのマージプロセスには、多くのリンクリスト操作が含まれます。頻繁なアプリケーションの中には、マージ直後に分割されることがあり、役に立たないため、パートナーシステムにはまだ問題があります。

6.スラブディストリビューター

バディシステムの導入から、割り当ての最小単位は4KBページフレームであることがわかります。これは、頻繁に要求される数十バイトのメモリでは依然として非常に無駄であるため、よりきめ細かいアロケータが必要です。 。スラブディストリビューターです。

スラブディストリビューターは、パートナーシステムから分離されているのではなく、パートナーシステム上に構築されています。パートナーシステムのセカンダリディストリビューターと見なすことができ、ユーザー側に近いです。ただし、スラブディストリビューターはユーザーに近いためです。 、それは構造の中にあります実現はパートナーシステムよりも複雑です、この記事は簡単に要約することができるだけです。

個人的には、スラブアロケーターのハイライトには次のものが含まれていると感じています。最小の粒度は、オブジェクトとメモリの戻りが遅いことです。

Linuxで使用されるスラブアロケーターの基本は、SunOSオペレーティングシステム用にJeffBonwickによって最初に導入されたアルゴリズムです。Jeffのアロケータは、オブジェクトのキャッシュを中心に展開しています。カーネルでは、限られたオブジェクトのセット(ファイル記述子やその他の一般的な構造など)に大量のメモリが割り当てられます。Jeffは、カーネルで通常のオブジェクトを初期化するのに必要な時間が、それらを割り当てて解放するのに必要な時間を超えていることを発見しました。したがって、彼の結論は、メモリをグローバルメモリプールに解放して戻すべきではなく、メモリを特定の初期化状態に保つ必要があるというものです。
「Linuxスラブアロケータの分析」より

スラブがオブジェクトを最小単位として使用する理論的根拠は、構造を初期化する時間が割り当てと解放の時間を超える可能性があるということです。

スラブアロケーターは、スーパーマーケットが一般的に使用されるアイテムを誰もが見つけやすい場所に配置するのと同じように、メモリの事前割り当てメカニズムと見なすことができます。これらのオブジェクトは、事前にアプリケーションの準備ができたらすぐに割り当てることができます。
ここに画像の説明を挿入

slabs_full:リンクリスト内のスラブが完全に割り当てられました
slabs_partial:リンクリスト内のスラブが割り当てられました
slabs_empty:リンクリスト内のスラブは無料です。つまり、リサイクル可能な
オブジェクトが割り当てられ、スラブから解放されます、各kmem_cacheスラブリストは状態移行の対象ですが、スラブの再生された部分はすぐにパートナーシステムに返されず、割り当て時に最後にリリースされたオブジェクトが最初に割り当てられます。目的は、ローカリティの原則を使用することです。見ることができるcpuキャッシュの詳細スラブアロケータの詳細で十分ですが、この複雑なロジックを実装するには、複数のキューを維持することはパートナーシステムよりも複雑です。

スラブの内容はバディよりも複雑なので、この記事は拡張しません。

7.結論

Linuxのメモリ管理については確かにたくさんのことがあります。この記事は簡単な説明です。深く理解するには、カーネルの本を読む必要があります。近道はありません。

おすすめ

転載: blog.csdn.net/qq_40989769/article/details/112368982