web-dev-qa-db-ja.com

仮想メモリは実際にどのようにメモリスペースを増やしますか?

仮想メモリは、実際に利用可能な量よりも多くのメモリを表示することによってプログラムを欺くことを理解しています。

しかし、最終的には論理アドレスを実際の物理アドレスにマッピングする必要があります。今それはどのようにメモリを増やしているのでしょうか?

69
Ahti

physicalmemoryはまったく増加していません。その目的はまったく別のものです。それができることはプログラムが物理的に利用可能であるより多くのメモリを使うことを可能にする他のバッキングストアを利用可能にすることです。

仮想メモリは、プロセスを互いに分離して分離するために使用され、メモリアクセスを別の場所に転送することも可能にします。

仮想メモリを使用すると、システムはすべてのプロセスに他のプロセスから分離された独自のメモリスペースを割り当てることができます。プログラムがそれ自身の空間で効果的に動作すると、「同じ」アドレスを使用する必要があるかもしれない他のプログラムを回避する必要がなくなり、アドレス空間全体へのフルアクセスが可能になります。プロセスは互いに容易に干渉できないため、これには信頼性とセキュリティの向上という副作用があります。

アプリケーションの仮想メモリ空​​間は必要に応じて構築されます。アプリケーションは(それ自体は)1つの連続したメモリブロック内にあるように見えますが、実際には物理メモリ全体に完全に分散している可能性があります。

仮想メモリでは、メモリアクセスをトラップして転送することもできます。これにより、スワップファイルなどの機能を使用できます。これは、最近使用されていないメモリの一部をディスクにプッシュし、「このメモリブロックはファイルxの場所yにある」というポインタを設定してから、物理メモリを解放できることを意味します。他のアプリケーションが使用するための領域。アプリケーションがそのメモリを必要とするとき、それをディスクから読み戻すことができ、物理的なRAMの場所に配置し(以前とは異なる可能性があります) 。

ページファイルが使用されるのと同じように、仮想メモリは、オペレーティングシステムがプログラムのために共有ライブラリを効果的に「遅延」ロードすることを可能にすることもできます。メインプログラムが特定のライブラリを使用することをオペレーティングシステムに指示すると、オペレーティングシステムはライブラリの要件をチェックし、アプリケーション用の仮想メモリ領域にスペースを割り当てることで、ライブラリ全体をロードするのではなく時間を節約できます。実際に必要になるまで、ライブラリのページをディスクからロードするのを遅らせることができます。このようにRAMにロードされるライブラリの唯一の部分はプログラムによって実際に使用される部分であり、決して使用されない部分は決してロードされないのでRAMを無駄にしません。

これらの技術を使用して、システムの安定性を向上させ、過度に影響を与えることなく、限られたスペースでより多くのプロセスを実行できるようにします。それは「メモリを増やす」のではなく、代わりに私たちが持っているものをより効果的に使うことを可能にします。

スワップファイルは仮想メモリシステムによって有効にされますが、以前は仮想メモリと混同されていました。

116
Mokubai

素人の説明

そのメモリが使用されるとき、システムは各仮想アドレスを物理アドレスにマップする必要がありますが、すべてのメモリが同時に使用されるわけではありません。たとえば、ブラウザに20のタブがあり、各タブに1GBのメモリがあるとします。仮想メモリをサポートしていないOSでは、これを機能させるためには20GBのRAMが必要です。秘訣は、20個のタブすべてを同時にブラウズするのではないので、仮想メモリを搭載したOSでは、わずか2GBのRAMを使用してブラウザをそのように使用できるようにすることです。

より複雑な側面

仮想メモリは、スワップ専用には使用されません。主な目的は、実際には仮想メモリ管理のないシステムでは大きな問題となるRAMフラグメンテーションを回避することです。1[GB]のRAMが空いている場合もあります。 10MB、100MBを要求するアプリケーションは動作できません。

時間の経過とともに、仮想メモリはさらに多くの用途、特にランダムファイルアクセスを発見しました。データベースのような多くのアプリケーションは、ファイルを順番に読むことを強いられると非常に遅くなります。 )メモリを最適化し、アクセスパターンに基づいてディスクIOおよびキャッシュを最適化します。

21

実際にメインメモリハードウェアを追加するという意味で、仮想メモリはメモリを増やすことはありません。しかし、それは使用可能なアドレスの範囲を広げることができます。そのため、コードセグメントとデータ(スタック&ヒープ)セグメントで構成される実行中のプログラムを作成することができ、これらは両方とも、仮想アドレスの範囲よりも大きい範囲を占有できます。 マシンの物理的に実記憶スペースによって提供される物理アドレス。トリックは、それらの仮想アドレスのほんのわずかな部分だけがいつでも物理的なメインメモリによってバックアップされることです[しかし、すべては最終的にディスク記憶装置によってバックアップされます]。これは、参照の局所性の現象が原因で機能します。常に、プログラムセグメントの1つ以上の小さな連続したセクションの命令だけが実行され、1つのデータは1つのデータだけが実行されます。 [もちろん、動作は実際にはもっと複雑ですが、かなりの時間にわたってこのパターンに従います]

5
PMar

私は、仮想メモリは実際に利用可能な量よりも多くのメモリを表示することによってプログラムを欺くことを理解しています。

仮想メモリの当初の動機は、物理メモリよりも大きいアドレス空間を提供するというメモリ管理の形式でした。
実際にインストールされた物理メモリはその数のほんの一部であったが、ソフトウェアはCPUの全アドレス空間(例えば2 32のアドレス空間)を利用することができる。
大きなプログラムは、巨大な(インストールされた)メモリ要件を課すことなく仮想メモリを使用したコンピュータ間で移植可能であり得る。
この仮想メモリの使用は、メインフレームコンピュータとフェライトコアメモリ(これは物理的に低価格で高価なものでした)の時代に遡ります。

しかし、最終的には論理アドレスを実際の物理アドレスにマッピングする必要があります。今それはどのようにメモリを増やしているのでしょうか?

仮想メモリは、プログラムにより多くのアドレス空間を提供するための単なる手法から進化しました。
仮想メモリは、現代のオペレーティングシステムにおける各プロセスにセキュリティを提供する際の重要な構成要素であり、そのため、プロセスは他のプロセスに干渉することも、他のプロセスによって損なわれることもない。
しかし、仮想メモリを使用したマルチプロセッシング(multiprocessまたはsと混同しないでください)を使用しても、物理メモリよりもシステムに見かけのメモリが多くなります。

作成された各プロセスはそれ自身の仮想アドレス空間、すなわちそれ自身の仮想メモリを備えている。
各プロセスで実際に使用されている(そして仮想メモリーにマップされている)物理メモリーの量は動的です。通常、プロセスの実行を実行するためのコード(別名テキスト)およびデータページ/セグメントを含む仮想メモリのみが、別の物理メモリ(別名、メモリに常駐)にマップされます。

不要なコード(現在実行されていないため)およびデータ(参照/処理されていないため)は、常にメモリに常駐する必要はありません。コードおよび/またはデータページ/セグメントは、バッキングストアに「スワップアウト」され(例:HDDまたはSSD上のスワップスペースまたはページファイル)、後で必要に応じて「スワップイン(バック)」(別名「オンデマンド」) ).

仮想メモリは、それぞれが保護された仮想アドレス空間を持つ多数のプロセス間での有限物理メモリの効率的な使用を容易にします。これらの仮想メモリの合計は、通常、取り付けられている物理メモリよりも大きくなります。
「メモリの増加」は、プログラムの観点だけでなく、システムの観点からのものです。

4
sawdust

仮想メモリは、プログラムがアドレス指定できるデータ量を増やします。ソフトウェアの観点から、私たちは(一般的に)それらがどこにデータが保存されるかを気にしません。それは物理的なDRAMメモリに保存することも、マシンに接続されたフラッシュドライブに保存することも、回転するPlatterに保存することもできます。ソフトウェアが気にしているのは、そのデータへのアクセスを要求したときに成功するということです。

実際には、プログラムを高速に実行したいとも思っています。 速度を考慮すると、データがどこにあるかに注意します。最も頻繁にアクセスしているデータは、最速のアクセスを可能にするハードウェアに格納されることを望みます。私たちのプログラムはのように完全にDRAMを使い果たしたいと思います。しかし、これを実行するのに十分なDRAMがないことがよくあります。仮想メモリは解決策です。

仮想メモリでは、オペレーティングシステムはしばらくの間使用されていないデータを「ページアウト」してハードディスクに保存します。これはまだアクセス可能で、遅いだけです。プログラムがハードディスク上のデータを要求した場合、オペレーティングシステムはディスクからデータを読み取り、それをDRAMに戻すために時間をかけなければなりません。

理論的には、ディスクから直接データを読み取ることができます。しかし、そうではない理由があります。プログラムはこれらの合併症のすべてを知っている必要はありません。私たちは、データをインテリジェントにディスクに書き込むソフトウェアを書くことができ、またそうしています(これをキャッシングと呼びます)。しかし、それは多くの余分な作業を必要とします。我々がコードでそれをすることができる最も速い:

if data is not in memory
    read data from disk into memory
operate on data

鋭い読者は、データがメモリにあるとしても、それがそこにあるかどうかをチェックするための条件を持たなければならないことに気づくでしょう。これは単にメモリ内で直接操作するよりもはるかに遅くなります。

仮想メモリは、CPUのハードウェアをチェックインすることによってこの問題を解決します。 CPUは、ハードウェア専用にできるため、この仮想メモリ操作を非常に迅速に実行することができます。ソフトウェアだけでこれを実行しようとすると、CPUの汎用部分を使用する必要があります。これは、専用のトランジスタよりも当然遅くなります。

これが、ディスクからデータを読み込んでそのまま残すのではなく、常にデータをページングしてメモリに戻す理由です。メモリを「ページ」に分割します。各ページは、メモリ内に存在するか存在しないかのいずれかとしてマークされます。オペレーティングシステムは、このテーブルを、CPUが直接使用するのに便利な形式で維持します。プログラムが存在するデータにアクセスするときはいつでも、CPU上のハードウェアはそれらにDRAMのデータへのアクセスを直接与えます。データが存在しない場合は、「ページフォルト」が発行され、オペレーティングシステムにそのページをディスクからメモリの物理ページにロードし、テーブルを更新してCPUをこの新しい物理ページに向けるように指示します。

この問題全体の秘訣は、その使用を最小限に抑えることです。実際には、オペレーティングシステムは、どのデータをメモリに保持し、どのデータをディスクにページアウトするかを選択するのに非常に優れているため、大多数のメモリアクセスはページフォルトを引き起こすことなく発生します。

3
Cort Ammon

これは、マップエントリを一時的にすることによって行われます。

プログラムが論理アドレスにアクセスすると、CPUはマップ内で対応する物理アドレスを探します。見つかった場合、メモリアクセスは期待どおりに進行します。見つからない場合は、物理アドレスを割り当て、コンテンツを他のストレージからロードする必要があります - 「スワップスペース」。すべての物理アドレスがすでに何らかの論理アドレスに割り当てられている場合は、物理アドレスを使用可能にするために、いくつかの論理アドレスを「スワップアウト」して(スワップスペースに戻して保存しなければなりません).

最大割り当てメモリはスワップ空間のサイズで、取り付けられているメモリよりはるかに大きくなる可能性があります。スワップスペースを「実際の」メモリとして、RAMをスワップスペース用の高速キャッシュとして考えると便利です。

(これは徹底的な説明には程遠いです、それは関連しているが不必要な詳細に入らずに即時の質問に答えることを意図しています。)

2
ShadSterling

基本的な概念は、現代のCPUが「どのアドレス範囲に特定のプロセスが使用されるように割り当てられ、どの物理アドレス(メモリバス上のA00..Axx行と考える)を追跡しながら変換テーブルを管理できるという事実に依存します"IF ANY"は、 "none"が可能で許容できる状態であるため、この場合は、エラー状態(いわゆる "ページフォルト")がハードウェアレベルで発生します。 - このエラーはOSレベルのハンドラを起動します。例えばスワップファイルに書き込まれたメモリの内容を物理メモリの任意の空き位置に読み込み(読み込みの場合)、実際の場所を見つけることができます。書き込みの場合は、前述の変換テーブルを更新し、そのメモリにアクセスしようとしたプロセスに手動で制御を戻すことができます。

1
rackandboneman

仮想メモリ

1)大きな仮想アドレス空間をより少ない量の物理メモリにマッピングすることを可能にし、過剰にディスクまたはSSDに、または将来的にはNVRAMおよび他のデバイスに「スワップアウト」する。

2)より大きな仮想アドレス空間(たとえば64ビット)をより小さな物理アドレス空間(たとえば32または64ビット)にマッピングすることを可能にする。

3)より小さな仮想アドレス空間(たとえば32ビット)をより大きな物理アドレス空間(たとえば40ビット)にマッピングすることを可能にし、それによってより古いアプリケーションがより多くの物理DRAMを利用することを可能にする。

4)物理アドレス空間において断片化され隣接していない物理メモリを仮想アドレス空間において隣接させることができる。

5)プロセスがそれら自身の仮想アドレス空間を与えられ、従って互いに分離されることを可能にする。

6)偶然同じデータ値を共有する異なる仮想アドレスが単一の物理ページを割り当てることを可能にする。

これは単一のプロセスまたはOS内で発生する可能性があります。ほとんどのBSD UNIX派生OSは、読み取り専用のゼロページを1つ持っています。ページの共有を解除して書き込み可能にします。

プロセス間で発生する可能性があります。 UNIXのfork()は、COW方式でほとんどすべての仮想メモリを共有する子プロセスを作成します。

OS間で起こる可能性があります。仮想マシンホスト上のゲストOSでは、ページの重複排除、COWの共有などが可能です(最近のセキュリティ攻撃の中には、これを利用しているものもあります)。

7)仮想メモリは、仮想アドレス空間の一部をファイルに、または同じマルチプロセッサシステム内であろうとインターネット上であろうと、他のプロセッサ上にマッピングされたメモリにマッピングすることを可能にすることができる。

0
Krazy Glew