オペレーティングシステム – 仮想メモリは実際にどのようにメモリ容量を増やしているのか?

memory operating-systems virtual-memory

仮想メモリが実際に使用可能なメモリよりも多くのメモリを表示してプログラムを誤魔化すことは理解しています

しかし、最終的には論理アドレスを実際の物理アドレスにマッピングしなければなりません。さて、どうやってメモリを増やしているのでしょうか?

  73  Ahti  2017-01-10


ベストアンサー

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

仮想メモリは、プロセスを互いに分離・隔離したり、メモリアクセスを別の場所に流用したりするために使用されます

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

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

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

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

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

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

117  Mokubai  2017-01-10


Layman’s explanation

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

より複雑な側面

仮想メモリはスワップ専用ではありません。これは、仮想メモリ管理のないシステムでは大きな問題となります

データベースのような多くのアプリケーションは、ファイルを連続的に読まなければならない場合は苦痛なほど遅くなり、OSがファイル全体が(仮想)メモリにあるふりをさせて、アクセスパターンに基づいてディスクのIOとキャッシングを最適化すれば、はるかに高速に動作します

21  Dmitry Grigoryev  2017-01-10


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

6  PMar  2017-01-10


仮想メモリが実際に使用可能なメモリよりも多くのメモリを表示してプログラムを誤魔化すことは理解しています

仮想メモリの元々の動機は、物理メモリよりも大きなアドレス空間を提供するためのメモリ管理の一形態でした。 ソフトウェアは、実際にインストールされている物理メモリがその数分の一であるのに対し、CPUのアドレス空間(例えば2^32アドレス空間)をフルに利用することができました。 大規模なプログラムは、仮想メモリを使用するコンピュータ間で、巨大な(インストールされた)メモリ要件を課すことなく移植することができました。 このような仮想メモリの使用は、メインフレームコンピュータやフェライトコアメモリ(物理的に密度が低く高価な)の時代にさかのぼります

しかし、最終的には論理アドレスを実際の物理アドレスにマッピングしなければなりません。さて、どうやってメモリを増やしているのでしょうか?

仮想メモリは、単にプログラムのためにより多くのアドレス空間を提供するための技術から進化してきました。 仮想メモリは、あるプロセスが他のプロセスに干渉したり、他のプロセスに侵害されたりすることがないように、現代のオペレーティングシステムの各プロセスにセキュリティを提供するための重要なコンポーネントです。 しかし、仮想メモリを用いたマルチプロセッシング(マルチプロセッサと混同しないでください)では、物理メモリよりもシステムの見かけ上のメモリを提供することに変わりはありません

作成された各プロセスには、独自の仮想アドレス空間、すなわち独自の仮想メモリが提供されます。 各プロセスに実際に使用される(仮想メモリにマッピングされる)物理メモリの量は動的です。典型的には、プロセスの実行を実行するためのコード(別名テキスト)とデータページ/セグメントを含む仮想メモリのみが物理メモリにマッピングされます(別名メモリ内常駐)

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

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

4  sawdust  2017-01-10


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

実際には、プログラムを高速に動作させたいと考えています。速度を考慮すると、データがどこにあるかは気になります。最も頻繁にアクセスするデータは、最速のアクセスを可能にするハードウェアに保存したいと考えています。私たちのプログラムは、完全に 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  2017-01-10


これは、マップエントリを一時的なものにすることで行います

プログラムが論理アドレスにアクセスすると、CPUは対応する物理アドレスをマップ上で探します。見つかった場合、メモリアクセスは期待通りに進行しますが、見つからなかった場合は、物理アドレスを割り当てて、他のストレージ、つまり「スワップスペース」から内容をロードしなければなりません。すべての物理アドレスがすでにいくつかの論理アドレスに割り当てられている場合、物理アドレスを利用できるようにするために、いくつかの論理アドレスを「スワップアウト」(その内容をスワップスペースに戻して保存)しなければなりません

最大割り当てメモリはスワップ空間のサイズであり、インストールされているメモリよりもはるかに大きくなる可能性があります。スワップスペースは「本当の」メモリであり、RAMはスワップスペースのための高速キャッシュであると考えると便利かもしれません

(これは徹底した説明とは程遠いもので、関連するが必要以上の詳細には触れずに、当面の質問に答えることを目的としている)

2  ShadSterling  2017-01-11


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

1  rackandboneman  2017-01-10


Virtual memory:

1) 大規模な仮想アドレス空間をより少ない量の物理メモリにマッピングし、余剰分はディスクやSSDに、あるいは将来的にはNVRAMや他のデバイスに「スワップアウト」することができます

2) より大きな仮想アドレス空間(例えば64ビット)を、より小さな物理アドレス空間(例えば32ビットや64ビット)にマッピングすることができます

3) 小さい仮想アドレス空間(例えば32ビット)を大きい物理アドレス空間(例えば40ビット)にマッピングすることで、古いアプリケーションでもより多くの物理DRAMを利用できるようになります

4) 物理アドレス空間で断片化されて非連続な物理メモリを仮想アドレス空間で連続化することを可能にします

5) は、プロセスに独自の仮想アドレス空間を与え、それゆえに互いに分離することを可能にします

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

これは単一のプロセスや OS の中で起こる可能性があります – ほとんどの BSD UNIX 由来の OS はゼロの読み取り専用ページを持っていて、それを任意のゼロで埋め尽くされた仮想ページにマップすることができます

これはプロセス間で発生する可能性があります – 例えば、UNIX の fork() は、COW 方式でほぼすべての仮想メモリを共有する子プロセスを生成します

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

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

1  Krazy Glew  2017-01-17


タイトルとURLをコピーしました