応用情報技術者試験を勉強していたら、ページフォールトに関する問題が出た。
JavaScriptとRubyをメインにして仕事をしているため、ページ?ページングのこと?だと思っていたけど、全然違った内容だった。
ローレイヤーの言語をちゃんと触ったことないので、ネットで検索している情報だとあまり伝わらなかった。なんとかページフォールトを理解するまでの流れを残してみた。
ページフォールトとは?
ページフォールト(page fault)とは、ページング方式の仮想記憶(仮想メモリ)において、プログラム(プロセス)がアクセスしようとした仮想メモリ領域(ページ)が物理メモリ上に無く、ストレージに退避していることが分かったときに発生する例外あるいは割り込み処理。
なるほどわからん。そもそも仮想メモリとは?
仮想メモリとはパソコンのハードディスクやSSDなどストレージの一部をメモリとして使うことで、メインメモリの容量が足りなくなったときにタスクを実行するための一時的な作業スペースとして機能します。
実際の物理メモリよりもっと大きなメモリを使っているように動作させることができるらしい。
ページは何?
この仮想メモリは大きな配列になっている。
以下のようにアドレスを配列の中に入れていくことになる。
['アドレス1', 'アドレス2', ... , 'アドレスn']
このような配列を4GB分持っていると思うと、大きさが2^35 = 34,359,738,368ビットの配列になる。
これを毎回検索するのは効率が悪いし、ポインターで指定するときに「23,090,112,910番目のアドレスを指定します」みたいなことをしないといけなくなるので不便なところがある。
そこで、ページを利用するとこの仮想メモリを二次元配列で表すことができる。
エクセルのように整理ができるイメージ!
各セル:メモリのアドレス
行:ページ
列:ページ内の位置(distance, offsetと呼ぶ)
なので、ページは仮想メモリを二次元配列で管理する単位だと考えられる。
それではページフォールトとは?
以下のような例を考える。
[ページ 1] [1][2][3][4]
[ページ 2] [5][6][7][8]
[ページ 3] [ ][ ][ ][ ] <- まだロードされていないページ
[ページ 4] [9][10][11][12]
もしプログラムがページ3の1個目のアドレスにアクセスしようとしたら、このページはまだロードされていないためページフォールトが発生する。
Webで言うと404 Not Foundレスポンスに近いのかな?
ページフォールトが発生した後の処理
OSがページフォールトを検知すると、抜けているページをディスクから物理メモリに持ってくる。
そこで、また仮想メモリテーブルをアップデートし、ページのアドレスを記録する。
その時の二次元配列は以下のような形になる。
[ページ 1] [1][2][3][4]
[ページ 2] [5][6][7][8]
[ページ 3] [13][14][15][16] <- ページをロード
[ページ 4] [9][10][11][12]
おわりに
こうやって知らなかったものを勉強していると、まだまだ知らないことがいっぱいあることを実感する。
長い目で見ると、ローレイヤーもちゃんと勉強するべきだな...