【基礎】仮想記憶とは | 若手エンジニアのブログ

若手エンジニアのブログ

文系出身の若手女子エンジニアによる技術ブログ。
日々の経験や学びをアウトプットするためにブログを書いています。
バックエンド(Java+SpringFramework)を経てインフラエンジニアになりました。
今は育休中につき、本で勉強したことを中心にアウトプットしています。

今日は、仮想記憶の技術について書いていきます。

 

仮想記憶は、これまで「何となく知ってるけど、自分の言葉で説明できひんわ…」

という典型ワードやったので、ちゃんと勉強することにしました(`・ω・´)

 

もくじ

1.仮想記憶とは

 ・概要

 ・仮想記憶を使う理由

2.仮想記憶のしくみ

 ・仮想記憶空間の見た目

 ・アドレス空間とは

 ・物理アドレスとは

 ・仮想アドレス(論理アドレス)とは

3.仮想記憶の注意点

 ・ページング

 ・ページフォールト

 ・スラッシング

4.まとめ

 

1.仮想記憶とは

◎概要

まずは教科書的な説明から。

 

仮想記憶とは、実メモリの物理的なアドレス空間とは別に、

仮想アドレス(論理アドレス)を割り当ててメモリ内容を管理する記憶方式。

実メモリと、ストレージ(HDDやSDDなどの外部記憶装置)の一部をあわせて、

あたかも1つのメモリのように見せかける。

 

…と言ってもイメージしづらいと思うので、まずは仮想記憶を利用する理由を説明した後、

各用語の意味と、仮想記憶利用時の注意点を順に解説していきたい。

 

◎仮想記憶を使う理由

そもそもコンピュータ(OS)の処理は、CPUによって行われる。

しかしCPUは処理をする(データを演算する)のみであり、自分ではデータを覚えておけない。
CPUとデータを直接やりとりし、記憶する役割を担うのは、メモリである。

 

しかしメモリにも容量があるので、当然ながら、容量を超えてしまうと、必要なデータを覚えておくことができない。

一番良いのは、メモリの搭載容量を増やすことだが、メモリは高価である。

気軽に増やせるわけではない。

 

一方で、メモリに比べてストレージは安価なので、増設しやすい。

 

そこで、ストレージの領域の一部を、あたかもメモリとして扱う領域とすることで、
実質的にメモリとして扱える容量(メモリの記憶容量)を増やす方式、すなわち仮想記憶を用いれば、
実メモリの容量不足&コスト高を解消することができる。

 

 

2.仮想記憶のしくみ

◎仮想記憶空間の見た目

仮想記憶では、メモリを利用する側=アプリケーション、システムプログラム等からは、

「実メモリ」と「ストレージの、あたかもメモリとして扱う部分」の区別はなく、

丸ごと1つのメモリとみなされる。

アプリケーションは、仮想記憶の技術が使われているかどうかを意識することなく、
実メモリを利用するかのように、大きなメモリ容量を簡単に利用できるということだ。

 

アプリケーションが仮想記憶の記憶領域(仮想アドレス空間)を利用する際は、

「仮想アドレス」を用いて必要なデータにアクセスする。

 

◎アドレス空間とは

※以降、アドレス空間、物理アドレスとは何かを説明していきます。
アドレス空間についてご存じの方は適当に読み飛ばしてください。

 

仮想記憶を用いているかどうかに関わらず、そもそも実メモリは、データを格納するためにアドレス空間を持つ。

 

アドレス空間は、メモリを大きな1つのマンションに例えるとイメージしやすい。

マンションにはたくさんの部屋があり、それぞれに101号室、102号室…などと部屋番号が割り振られている。

そして101号室には田中さん家族、102号室には佐藤さん家族…といったように、

各部屋番号と住人が紐づくことになる。

 

メモリもマンションと同様である。

メモリ内はたくさんのブロック(=部屋)に分かれており、各ブロックにはアドレス(=部屋番号)が割り振られている。

メモリでは、記憶すべきデータが出てきたら、空いているブロックにデータを格納していく。

このとき、ブロックにアドレスが割り当てられていることで、データをどこに格納したかが分かるようになっている。

部屋番号が割り当てられていることで、住人がマンションのどの部屋に住んでいるかが分かるのと同じイメージである。

 

 

以上のように、メモリにはデータを記憶するための小さなブロックがたくさんあり、

各ブロックの場所をアドレスで示していることから、メモリ内には「アドレス空間」が広がっているという。

 

◎物理アドレスとは

前述の通り、メモリ内は小さなブロック(=部屋)に分かれており、各ブロックにはアドレス(=部屋番号)が割り当てられている。

 

これらアドレスは、物理的に分かれたブロックに対して割り振っていることから、「物理アドレス」と呼ばれる。

 

難しく考えずに、今まで説明した「アドレス」の、別名と考えて差し支えない。

わざわざ「物理」とつけているのは、今回のテーマである「仮想記憶」を実現する、

「仮想アドレス(論理アドレス)」との対比を分かりやすくするためだと思われる。

 

◎仮想アドレス(論理アドレス)とは

仮想記憶では、ストレージのうち、メモリとして扱う領域と、実メモリの領域が合体し、
1つの大きなメモリ空間として扱われる。

 

この1つの大きなメモリ空間(仮想アドレス空間)においても、実メモリ内部と同様、
データを格納するためのブロックがたくさん用意される。

 

用意されたメモリ空間のブロックにアクセスするには、物理アドレスではなく、

「仮想アドレス」と呼ばれる別のアドレスが使われる。

 

イメージはこんな感じ。↓


仮想アドレスという用語も難しく考える必要はない。

仮想記憶でストレージの領域も増えたので、

  物理アドレスだけではメモリ空間へのアクセスができない
  →アクセスできるように別途番号を振っておこう

といった考えだと思ってもられば良いと思う。

 

もしくは、仮想アドレスは、アプリケーションからアクセスするためのインタフェースのようなものだと考えると、分かりやすいかもしれない。

 

アドレスについてまとめると、以下のようになる。

 ・物理アドレス=実メモリのメモリ空間のブロック番号

 ・仮想アドレス=実メモリ+ストレージでできた大きなメモリ空間のブロック番号

 

 

3.仮想記憶を利用する時の注意点

仮想記憶では、ストレージの一部をメモリのように扱うことで、
実メモリよりも大きなメモリ空間を確保できる。
 

けれども実態を考えると、実メモリとストレージは当然異なる。

 

つまり仮想記憶では、
ストレージをあくまでも見かけ上「メモリのように扱う」だけであって、

ストレージが物理的にメモリに置き換わるわけでは無いといことだ。

 

そのため、仮想記憶においては、ページング(またはスワッピング)と呼ばれる、
実メモリ⇔ストレージの、データの入れ替えが必要となる。

 

◎ページング(スワッピング)とは

仮想記憶では、基本的には実メモリ上にデータを記憶する。

しかし、実メモリが覚えきれない分のデータが出てくれば、
ストレージの、あたかもメモリとして扱う場所に退避することで、データの記憶を保持する。

 

「ストレージの、あたかもメモリとして扱う場所」は、「スワップ領域」や、「ページファイル」、「スワップファイル」などと呼ばれる。
※OSによって名称はまちまちだが、意味合いは同じである。本ブログでは、以降、「スワップ領域」と表すこととする。

 

ちなみに、実メモリ上からスワップ領域に、データを退避することを、
「ページアウト」または「スワップアウト」と呼ぶ。

 

また、スワップ領域にあるデータの読み出しは、実メモリで行う必要がある。
スワップ領域に退避したデータを、実メモリに移して読み出せる状態にすることを、「ページイン」または「スワップイン」と呼ぶ。

 

以上の、ページアウト/スワップアウトと、ページイン/スワップイン、
すなわちデータの入れ替え操作のことを、「ページング」または「スワッピング」と呼ぶ。

 

◎ページフォールト

仮想記憶の技術を用いていたとしても、

実メモリ上にデータが無いと、そのデータをCPUが読み出すことはできない。

 

そのため、もし仮想記憶内のデータ読み出し時に、

当該データが物理的にはストレージ内にあることが分かった場合、

「ページフォールト」という例外・割り込み処理が発生する。

 

ページフォールトが発生すると、OSによってページングが行われ、

必要なデータがストレージから実メモリに移動する(ページイン)。

(この時、実メモリにあった別のデータが、ストレージに移動することで、実メモリ上の容量が確保される。)

 

ページング後、改めてOSは当該データを読み出し、それまでの処理を再開することになる。

 

ページフォールトは、エラーではなく通常処理の1つであり、必ずしも悪いものではない。

しかし、例外や割り込み処理が多発すると、処理の遅延・性能低下につながってしまう(=スループットが低下する)。

 

ページフォールトの発生頻度をできるだけ減らすためには、スワップ領域をできるだけ小さくする必要がある。

スワップ領域が大きいと、ストレージへ退避されるデータ量もそれだけ多くなる。

すると必要なデータが、実メモリではなく、ストレージ内にある可能性が高まり、
プログラム処理中のページング多発につながってしまう。

 

以上より、仮想記憶の利用時は、ページフォールトの発生確率も考慮したうえで、
本当に必要なスワップ領域の大きさだけを確保するようにすべきである。

 

◎スラッシング

ページフォールトが頻発しすぎると、スラッシングという状態に陥ることもある。

スラッシングは、実メモリとストレージとのデータの入れ替えが多発し、

外部からの入出力を受け付けず、動作が極端に遅くなる現象である。
場合によっては障害になるかもしれない。

 

スラッシングは、スワップ領域が大きすぎる時や、そもそも実メモリが小さすぎる時に発生しうる。

どうしようもなく実メモリの容量が小さいときは、仮想記憶に頼る以前に、

どうにかコストを捻出して、実メモリの増設を検討することも視野に入れるべきである。

 

4.まとめ

本記事の要点は以下の通り。

 

・仮想記憶とは、実メモリの物理的なアドレス空間とは別に、
 仮想アドレス(論理アドレス)を割り当ててメモリ内容を管理する記憶方式である。

 

・仮想記憶によってストレージの一部をあたかもメモリのように扱うことで、
 メモリとして扱える容量を、低コストで増やせる。

 

・実メモリ⇔ストレージ間で、データの入れ替えが必要となる(ページング/スワッピング)

 

・OSの処理中にページングが必要になると、ページフォールトという例外が発生する

 

・ページフォールトが頻発すると、動作がほとんど進まない状態(スラッシング)に陥る

 

 

今回は以上!