プロセスその6
メモリが潤沢な最近ならこんな悩みはそれほど多くないのだろうが、メモリが乏しかった当時としては、これは非常に問題であった。プロセスに割り当てるメモリは、多すぎても少なすぎてもいけない事になるからだ。多すぎる、という事は他のプロセスに割り当てるべきメモリが減ってしまうことになるからだ。
そこで、プロセスに割り当てるメモリは動的に変更する、という仕組みが考えられた。要するに、各プロセスが、その時々で必要とするメモリ量に合わせてダイナミックに割り当てるメモリを変化させることで、メモリを効率的に利用しようという仕組みだ。例えば、通常アプリケーションは初期化のタイミングでは多めにメモリを利用する。初期化ルーチンが走るから、当然これを全部オンメモリで保持する必要があるし、初期化の過程で当然数多くのメモリ領域をアクセスする必要がある。ただし、初期化が終わってMain Loopに入ると、必要とするメモリ量は当然減ることになる。従って、プロセスの立ち上がり時には多目のメモリを割り当て、初期化が終わったら割り当てメモリ量を削減するというアプローチが効果的である。
Working Setとは、このメモリ量である。といっても、仮想記憶マシンの場合にメモリをBytes単位で管理していたら手間が掛かって仕方がない。そこで、ある程度のサイズをPageという単位で管理することになっている。VMSの場合これは512Bytesで、その後に登場したUNIXは1KB~4KB程度(VAX上で動く4.1BSDとかAT&TのV6などは、確か512Bytesを継承していたと記憶している)、Windowsの場合も32bitのx86の場合も4KBである。仮想記憶に割り当てるべきメモリは、全てこの512Bytesなり4KBなりのページという形で管理される。この結果、Working Setにおける管理単位は「何ページ」という形になる。このPageを管理するものはいくつかあるのだが、まず一番基本になるのが図1のPTE(Page Table Entry)である。これは1ページ毎に1エントリ存在しており、0~20までの21ビットがページの指定番号(PFN:Page Frame Number)で、31~21までの11ビットが管理領域になっている。
図1:PTE(Page Table Entry) |
このPTEを使うことで、「プロセスがそのメモリ領域を必要としているか否か」が簡単にわかる。具体的には、プロセスが占有しているPageを指すPTEは、あるリストに一覧の形で並んでいる。このリストに属するエントリのValid bit(31bit目)を定期的に全部Invalidに変更し、その後でそのPageが参照あるいは更新が掛かった場合、再びValidに戻す仕組みだ。これを行うと、ある期間の間に参照もされなければ更新もされないPageが判るので、こうしたページはまとめてPage outすることで、確保したものの使っていないPageを直ぐに再利用できる仕組みになっている。もっともこれは大雑把な話。実際にはもう少し細かい話になるが、ここではとりあえず割愛する。
では逆に、どうやって「そのプロセスがもっとメモリを必要としている」かを知るかというと、これはPage Faultの頻度を監視することで行っている。Page Faultというのは、各プロセスがあるPage領域をアクセスしようとしたときに、そのPageがメモリ中無かった(=Page Fileに格納されていた)場合に発生するイベントである。この場合プロセスの実行は一時的に停止され、そのPageが物理的にPage Inされるのを待つことになる。このPage Faultという現象そのものは仮想記憶では一般的な動作であり、「それが発生してはいけない」訳ではない(それが発生しない様にするためには、各プロセスに起動時に2GBの実メモリを割り当て、Working Setの調整を無効として固定するしかない)が、頻度が余り多いとパフォーマンスに深刻な影響が出ることになる。そこでWorking Setは、このPage Fault Rateが必要以上に大きくならない様に加減する必要になる。図2はWorkin Set Size(Working Setに割り当てるPage量)とPage Fault Rateの一般的な関係を示したものだ。概ねこの両者は反比例の関係にある事が経験則で知られており、割と加減がしやすい。この図2において、赤い部分はWorking Set Sizeが過小であり、Page Fault Rateが極端に大きくなりすぎ、システムへの影響が大きすぎる。一方黄色の部分はWorking Set Sizeが過大で、Page Fault Rateが不自然に小さくなりすぎている。勿論メモリが余っていればこれは大した問題ではないのだが、Page Faultの低下率がWorking Setの増大率に比べて割が合わないと看做すのが一般的だ。つまり水色の部分、適度なWorking Set SizeとPage Fault Rateを維持するのが基本ということになる(続く)。
図2:Working Set SizeとPage Faultの関係 |