0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

仮想記憶

Posted at

仮想記憶がない場合の問題点

メモリの断片化

プロセスが生成された後に、メモリの獲得、開放を繰り返すと発生する。
メモリの領域が細かく断片化され領域の確保に失敗する。
扱うデータが領域より大きいと失敗する。
プログラム側が断片化を意識して実行するので不便。

マルチプロセスの実現が困難

  • 同じプロセスを二つ同時に実行すると正しく動作しない
  • 違うプロセス同士を同じメモリ領域で実行できない

これらを意識して配置場所が重ならないように意識する必要がある。

不正な領域へのアクセス

カーネルやたくさんのプロセスがメモリ上に配置されている場合、あるプロセスがカーネルや他のプロセスに割り当てられたメモリのアドレスを指定すれば、それらの領域にアクセスできてしまいます。
このためデータの漏洩や破壊のリスクがあります。

気づき

メモリを使い続けるとごちゃごちゃしてリスクあるのか

参考

仮想記憶

仮想記憶は、プロセスがメモリアクセスする際に、システムに搭載されているメモリに直接アクセスさせるのではなく、仮想アドレスというアドレスを用いて,間接的にアクセスさせるという機能です。
...
メモリの実際のアドレスを「物理アドレス」
...
アドレスによってアクセス可能な範囲を「アドレス空間」と呼びます

物理アドレスを指定できない

readelfコマンドやcat  /proc/<pid>/mapsの出力で記載されたアドレスは実は、すべて仮想アドレスです。なお、プロセスから実際のメモリに直接アクセスする方法、言い換えると、物理アドレスを直接指定する方法はありません

気づき

前見ていたアドレスはすでに仮想アドレスだったのか。

ページテーブル

仮想アドレスから物理アドレスへの変換には、カーネルのメモリ内に保存されている「ページテーブル」という表示を用います。CPUはすべてのメモリをページという単位で区切っており、アドレスはページ単位で変換されます。
ページテーブル中の一つのページに対応するデータを「ページテーブルエントリ」と呼びます。ページテーブルエントリには、仮想アドレスと物理アドレスの対応情報が入っています。
...
ページテーブルを作るのはカーネルです。...カーネルはプロセス生成時にプロセスのメモリを確保して、そこに、実行ファイルの内容をコピーすると書きました。そのときに同時に、プロセスようのページテーブルも作るのです。プロセスが仮想アドレスにアクセスした際に物理アドレスに変換するのは、CPUの仕事です。

気づき

CPUは仮想アドレスから物理アドレスの変換を行い、仮想アドレスにアクセスされたときも物理アドレスに変換する他の部品のことなのにCPUはお世話をするのか。
カーネルは子プロセスを生成するときもプロセス専用のページテーブルを作成もするのか。
つまりページテーブルに対応されていなければアクセスできないのか。

ページフォールトハンドラ

ページテーブルが物理アドレス部分と対応していない仮想アドレスにアクセスするとページフォールトという例外が発生します。
...
ページフォールト例外によってCPU上で実行中の命令が中断されて、カーネルのメモリに配置されたページフォールトハンドラという処理が実行されます。
...

カーネルは、ページフォールトハンドラにおいて、プロセスによるそのメモリアクセスが不正なものであることを検出します。この後はSIGSEGVというシグナルをプロセスに送信します。SIGSEGVを受信したプロセスは、通常は強制終了させられます。

参考

ページフォールトハンドラを見てみよう

root@**********:************# go build segv.go 
root@**********:************#./segv
不正メモリアクセス前
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=]

goroutine 1 [running]:
main.main()
	/************/************/************/************/************/segv.go:9 +0x7b
root@**********:************## make segv-c
cc     segv-c.c   -o segv-c
root@**********:************## ./segv-c
Segmentation fault (コアダンプ)

気づき

エラーで終了している

仮想記憶による問題の解消の気づき

メモリの断片化

断片化していても仮想アドレスは一塊になっているよう見えるからプロセス側は楽に処理ができる

マルチプロセスの実現が困難

プロセスごとのページテーブルを作成しているので重複することはない

不正な領域へのアクセス

プロセス側から物理メモリを見ることができないから他にアドレスを指定できないから不正アクセスができない

感想

CPU、カーネルを使ってメモリの混雑状況の中うまくやっているんだな。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?