「メモリ管理」を1記事で徹底理解

V1.0: 物理アドレスを直接使用する

初期のコンピュータは 1 つのプロセスしか実行できず、メモリも数百 KB しかありませんでした。当時の世界は非常にシンプルで美しく、メモリ空間の一部は OS 用に確保され、図 1-1 に示すように、rest はプロセス専用でした。

この記事の特典として、無料の C/C++ 開発学習教材パッケージ、技術ビデオ/コード、主要メーカーからの 1,000 件のインタビュー質問 (C++ の基礎、ネットワーク プログラミング、データベース、ミドルウェア、バックエンド開発/オーディオなど) を受け取ることができます。およびビデオ開発/Qt 開発/ゲーム開発/Linuxn カーネルなどの高度な学習教材と最適な学習ルート) ↓↓↓↓以下を参照↓↓記事の下部をクリックして無料で入手してください↓↓

ただし、CPU のコンピューティング リソースをより効率的に利用するために、OS は複数のプロセスを「同時に」実行することをサポートする必要があります。このとき、メモリ空間は固定サイズに従っていくつかのブロックに分割され、各プロセスに属します。図 1-2 に示すように。

メモリの物理アドレスを直接使用するため、これらのプロセスが自分の領域にのみアクセスする「義務」であれば正常ですが、他のプロセスが他人の領域に侵入してランダムに動作した場合はどうなるでしょうか?制御性が問題になります。

V2.0: 抽象変換層を追加し、仮想アドレスを使用する

制御の強化、セキュリティ検証、動的割り当てなどの問題を検討する場合、多くの場合、「エージェンシー」の抽象化レイヤーを追加することが一般的な解決策となります。

2.0では、プロセスが物理メモリ空間を直接使用することはできなくなり、0からエンコードされた仮想アドレスを使用し、MMU(Memory Management Unit)変換によって実際のアドレスを取得し、データを取得できるようになりました。記憶から得たもの。

中間層の MMU は、仮想アドレスの有効性と合法性をチェックして、セキュリティを確保します。

メモリ空間の使用の柔軟性を考慮して、メモリは固定サイズ (通常は 4KB) に従ってページング (ページング) され、連続した仮想アドレス ページ (VP、仮想ページ) が物理アドレス ページ (PP、物理ページ) にマッピングされます。この柔軟な設計により、物理メモリのスペース使用率が向上し、メモリの断片化が軽減されます。

マッピングがあるので、マッピング関係テーブル、つまりページテーブル(Page Table)を格納するのは当然であり、キー値は仮想アドレスのページ番号(Virtual Page Number)である。

値は、物理アドレス ページ番号 (PPN、物理ページ番号) を含むデータ構造 (PTE、ページ テーブル エントリ) です。ページ テーブルは MMU には存在せず、メモリにも存在することに注意してください。

図 2-1 は、仮想アドレスから物理アドレスへの変換プロセスを簡単に示しています。

説明の便宜上、ここでのページ サイズは 16 バイト (2^4、オフセットは 4 ビットを占有)、物理メモリの合計サイズは 8 ページ (2^3、PPN は 3 ビットを占有) または 128 バイトに設定され、仮想メモリは最大 4 ページを使用します (2^2、vpn は2 ビットを占有します)。

MMU は 6 ビットの仮想アドレスを 7 ビットの物理アドレスに変換します。vpnからPPN への変換はページ テーブルを通じて完了しますが、オフセット部分は変更されません。

①V2.1時間の最適化:TLBキャッシュを増加

コンピュータの分野では、パフォーマンスの向上を考えるとき、キャッシュの使用は万能の解決策です。

その背後にある主な理由は、時間的/空間的局所性の理論に基づいています。時間的には、アクセスされたばかりのデータはすぐに再びアクセスされる可能性が高く、空間では、アクセスされたばかりの空間 x はすぐにアクセスされる可能性が高くなります。 x の後は、隣接するスペースにもアクセスされます。

当然のことながら、MMU に小さなキャッシュ スペース、つまり、最新のVPN -> PPN マッピング関係を保存する高速テーブル TLB (Translation Lookasid Buffer) を追加できます。

キャッシュがヒットした場合(TLB ヒット)、アドレス変換速度は大幅に向上しますが、キャッシュがミスした場合( TLB ミス)、ページ テーブルが再度クエリされます。

残念ながら、空間と時間は常に矛盾しています。TLB の容量が大きいほど、アクセス速度は遅くなります。メモリ内のページ テーブルを置き換えるのに十分な大きさの TLB を実装することはできません。したがって、TLB がほぼ満杯の場合、通常はおおよそのLRU アルゴリズムは、最も使用されていないユニットを削除するために使用されます。

図 2-2 と図 2-3 は、それぞれTLBヒットとミスの場合のプロセスを示しています。ヒットした場合、必要な物理メモリ アクセスは 1 回だけです。ミスした場合 PTE は物理メモリでクエリされます。最初に TLB. に更新され、次に実際のデータ アドレスにアクセスします。

②V2.2のスペース最適化:マルチレベルページテーブルとスワップパーティション

時間を最適化した後は、空間で何が最適化できるかを考えてみましょう。仮想メモリが増加すると、元の線形ページ テーブルが増加することに注意してください。

32 ビットの仮想アドレス (2^32) と 4KB (2^12) のページング サイズの場合、1M ページ (2^20) になります。

マッピング ユニット PTE が 4 バイトを占める場合、このプロセスのマッピング テーブルを格納するだけで 4MB が必要になります。

マシン上で 100 のプロセスが同時に実行されている場合、400MB のメモリ領域が消費されます! これはシステム全体にとって大きな無駄になります。

この無駄を回避するための鍵は、すべての仮想ページがそのマッピング関係を保存する必要があるわけではないということです。使用されていないページング グループの場合、それらを表すために使用できる PTE (ページ テーブル エントリ) は 1 つだけですが、継続的に使用されるシャーディング グループの場合は、複数レベルのマッピングを位置決めに使用できます。

図 2-4 は、第 2 レベルのページ テーブルのアドレス指定プロセスを示しており、この図では、第 1 レベルのページ テーブルの 1 つの PTE は 1,000 VP を表すことができます。

このようにして、中央にある多数のアイドル状態の VP をわずか数個の PTE で表すことができるため、ページ テーブルの合計サイズが大幅に削減されます。大容量で疎な仮想アドレス空間の場合も、同じ手順に従うことができます。さらにいくつかのレベルのページ テーブルを追加します。

貴重なメモリ領域をより効率的に使用するために、マルチレベルのページ テーブルによる調整に加えて、ディスク領域の一部、つまりスワップ パーティションを仮想メモリとして使用することでオープン ソースの効果を実現することもできます。

具体的には、上位層アプリケーションに提供される仮想メモリ空​​間は、実際に利用可能なメモリ空間よりも大きくなる可能性があります。

OS が使用頻度の低いメモリ データを時々スワップ パーティションにコピーし、メモリから消去する限り、新しいメモリ領域を継続的に提供できます。

仮想メモリのこの部分が読み取られた場合、スワップ パーティションからメモリに復元するだけですが、当然、この操作によりメモリの読み書き速度がある程度低下します。

図 2-5 にスワップ パーティション追加後のワークフローを示します。検索対象の PTE が TLB にもメモリにも存在しないことが OS によって検出されると、ページ フォールト例外がスローされ、OS はスワップ パーティションから非同期に検索します。スワップ パーティション PTE からメモリに書き戻すと、完了後に CPU が再試行を開始できます。

V3.0: 勝つためのトリックはなく、自動メモリ管理

上記の設計により、オペレーティング システムは、上位層アプリケーションにとって安全で快適な仮想楽園を構築します。この楽園では、アプリケーションは、実メモリの変換やアドレス指定などの面倒な事柄に注意を払う必要がなく、ただ単に malloc するだけで済みます。必要なときにメモリを適用し、不要なときに解放します。ドロップするだけです。

しかし、アプリケーションの複雑さが急速に増すにつれて、たとえそれが 1 エーカーの 3 分の 1 の土地であっても、適用されたメモリが省略やバグのために時間内に解放されないことがよくあり、メモリ リークが発生し、最終的にはアプリケーションがクラッシュすることがあります。 。

その結果、JVMに代表される一連の自動メモリ管理プラットフォームが登場し、参照カウントや到達可能性分析を用いてメモリ内のデータオブジェクトを定期的にスキャンすることで、データオブジェクトがリサイクル可能かどうかを識別し、マーククリアアルゴリズムと組み合わせます。 、コピーアルゴリズムなどを使用してメモリガベージコレクションを実装します。

ガベージ コレクターの具体的な実装は業界内で常に更新されているため、ここでは詳しく説明しません。

結論

この記事では、最も基本的な設計から始めて、徐々に仮想アドレス変換を導入し、次に時間と空間を最適化し、最後にアプリケーション層の自動メモリ管理メカニズムを導入します。段階的に、基本的な設計図を構築するのに役立つことを願っています。メモリ管理。

もちろん、スペースの制限により、実際のシステム設計の詳細は、この記事で紹介したものよりもはるかに複雑です。より多くのレベルのキャッシュとマッピングが導入され、メモリ使用効率を向上させるために、ハードウェア特性に基づいたより多くの最適化戦略が実装されます。 。

ただし、簡単に言うと、設計の核となるアイデアを理解してから、技術的な詳細に目を向けると、より早く理解できると思います。

著者: 李登輝

はじめに: Akulaku はシニア開発エンジニアです。現在、金融融資プラットフォームのアーキテクチャ設計とコア構築を担当しています。マイクロサービス システム、JVM 仮想マシン、オペレーティング システムの原理とメカニズムについて深い研究を行っており、優れた知識を持っています。難しいオンライン問題を見つけて解決する。

この記事の特典として、無料の C/C++ 開発学習教材パッケージ、技術ビデオ/コード、主要メーカーからの 1,000 件のインタビュー質問 (C++ の基礎、ネットワーク プログラミング、データベース、ミドルウェア、バックエンド開発/オーディオなど) を受け取ることができます。およびビデオ開発/Qt 開発/ゲーム開発/Linuxn カーネルなどの高度な学習教材と最適な学習ルート) ↓↓↓↓以下を参照↓↓記事の下部をクリックして無料で入手してください↓↓

おすすめ

転載: blog.csdn.net/m0_60259116/article/details/135201815