プロセスその9

そんなわけで、見た目はだいぶ異なるVMSとWindows NTだが、内部的には意外と近い事をやっているのではないか、と筆者は想像している。Windows NTには3種類のワーキングセットがある(7.9:上巻 P534)とされているが、これは定義の問題であって、Process Working SetとSystem Working Setで構造が異なるという話ではない。ましてやSession Related Working Setなど、普通に考えると何がProcess Working Setと異なるのかが理解できない。このあたりは、コンソールがあくまで単なる1デバイスでしかない、CUIベースのVMSと、コンソールが前提となっているWindows NTではプロセスの作り方に差があり、このために分けて扱っているというのが本当のところだと思う。

勿論厳密に言えば、各々のWorking Setで取り扱うべき対象が異なっている(このあたりはP534に詳しい)から、対象を分離した意味はあるのだが、その調整方法に関しては特にこの3つで異なっているという話は無い。WSQUOTA / ESEXTENT / WSDEFAULT / AWSMINという4つのパラメータに相当するものを内部でどう決めているか(これも恐らくKeBalanceSetManagerの仕事であろう)の詳細は明確になっていないが、大雑把に言えば同等のハンドリングを行っているのではないかと想像される。

無論開発時期が異なるから、Windows NTには新しい仕組みが色々投入されている。例えば7.10.1のメモリ配置ポリシー(上巻P540)にあたる機能はVMSには無い。また7.10.2(上巻P541)で説明があるとおり、VMSで言うWSQUOTAに当たる変数を、Windows 2000では実行優先度調整に関係して変更しているといった仕組みも目新しい。もっともWindows XPでこの機能が無くなったあたりは、恐らくインプリメントしてみたものの、思うほどの効果が得られなかったのではないかと想像される。もう一つ大きく異なるのは、WSMAXに許される最大値である。表7-17(上巻P541)にあるように、2GB~7GBという巨大な数字が割り当てられているのが判る。このあたりはVMSと異なり、ある特定のプロセスが巨大なメモリを占有して使う、といった使い方のニーズがそれなりにあり、これに対応したためだと想像される。実のところ、巨大なメモリ空間を使いたいというニーズは昔から多く、こうした場合にはWorking Setの対象となるPaging Memoryではなく、Non Page Memoryをまとめてガバっと確保し、それをプロセス空間にマッピングして使うという方法が一般的だった(し、今も一般的な手法だと思う)。

VMSではPrivate SectionあるいはGlobal Section、WindowsではNon Page Poolという名前で提供されているが、これらを使うとそもそもPagingの対象とならないから、Working Setの縛りは発生しない。おまけにPaging対象外だから、そのメモリがSwapoutされたりする心配もない。このため、大量のデータ転送用バッファなどを確保する必要がある、一部の制御系システムにおいては愛用されてきた機能である。ただ使い勝手はあまり良くない(Non Page Poolに関する解説は上巻P466以降にある)上に、Pagingされることが必要なニーズには使えないため、逆に制御系以外のプログラムでは巨大なWorking Setを扱えるほうが好ましい、ということであろう。

図2

さて、話を再びWorking Setに戻す。Working SetはそんなわけでPaging単位の物理メモリの集合体ということになる。この物理メモリを管理するのが、PFN(Page Frame Number)である。物理メモリはページ(VMSなら512Bytes、Windows系はデフォルト4KB)単位で区切られ、ユニークな番号(PFN)が割り振られる。システム中でこのPFNを管理するのが、PFN Databaseと呼ばれるものである。このPFN Database、VMSの場合は図2の様に、8種類のテーブルから構成される構造になっている。ここで、

  • PFN Array:システム空間の仮想メモリに当てられているPageのPFNを格納する。
  • BAK Array:Backing Store(利用済のページ)Listに当てられているPageのPFNを格納する。Backing Storeについては後述。
  • FLINK/BLINK Array:FLINKは、未使用Page ListのPFNの順方向リンク、BLINKは逆方向リンクである。VMSは未使用Page Listを双方向リンクの形で保持しており、これを管理する。
  • SHRCNT Array:これは複数のプロセス間で共有されているPageのPFNを格納する。
  • WSLX Array:これがWorking Setに利用されているPageのPFNを格納する。
  • REFCNT Array:あるPFNの物理ページが何回参照されたかを格納する。これはDMAなどで特定の物理ページがアクセスされ、それがすぐさま提供できなかった場合にカウントされる。
  • SWPVBN Array:I/Oを行っているプロセスがSwapoutされた場合に、そのSwapoutされた先のVBN(Virtual Block Number:VMSにおいてディスク管理に使うもの。意味合い的には、IDEなどのLBAに近い)を格納する。これを格納しておくことで、I/Oが発生した場合にただちにSwapinしてI/Oを続行できる。
  • STATE Array:各PFNで示される物理メモリの状態を保持する。そのPageがFree Page Listに乗っているのか、Modified Page Listに乗っているのか、あるいは現在利用中でValidなのか、といった情報がここに格納される。
  • TYPE Array:各PFNで示される物理メモリの用途を保持する。つまりProcess Page / System Page / Global read-only Page / Global read-write Page /...といった具合に、どんな用途に使われているかがここに格納される。

といった具合になっている(続く)。