プロセスその13

そんなわけで、こうした共有ライブラリはGlobal Sectionに置かれる事になった。これなら複数のプロセスが同時にMappingできるし、Global Sectionは構造上システムが管理するから、利用していたProcess終了時の取り扱いに悩むこともない。Page Outされる危険性もないという訳だ。さて、話を戻すと、こうしたケースではライブラリをGlobal SectionにMapするのが一番高速ということになる。また一般的にこうした使い方がどの程度あるかは判らないが、ある特定のプロセスだけがRead/Write可能でFileをSectionにMappingし、他のプロセスはこれをRead Onlyで参照するなんてケースでもGlobal Sectionを使えるだろう。ただ、逆に言えばGlobal SectionでFileをMappingするのはこの程度で、後は純粋にプロセス間のデータ交換の目的で使うということになる。

さて、話がだいぶ逸れてきたので元に戻そう。VMSにおけるSectionは、20回でも説明したとおり、Paging対象外となるが、WindowsにおけるSection ObjectはPagingの対象になる(上巻P450)点が大きく異なる。この結果、21回目で指摘した諸々の問題をWindowsはかなり苦労しながら解決している。例えばあるSection ObjectがFileをMappingしており、しかも複数のObjectがこれを参照している場合のFlushの手順が11.7.2章の「マップドファイルのフラッシュ」(下巻P239)に説明されているが、こうした問題の解決のためにキャッシュマネージャは余分な作業を行わなくてはならない事が説明されている。では、こうした手間を掛けてまでSection ObjectをPaging対象にしたのは何故か? というと、まず考えられるのはメモリの効率的利用であろうと想像される。

例えば共有ライブラリをGlobal Sectionに置くことのデメリットは何か? というと、これをUnloadするメカニズムがデフォルトでは用意されないことだ。勿論そのDLLをUnloadするようなプログラムを作ることは不可能ではないが、OSが勝手にこうした処理をする訳ではない。これらのライブラリをダイナミックにロードする(つまり必要になるまでロードしない)形での節約はできるが、不要になった(この判断が実は難しい。例えばCのラインタイムライブラリは、恐らくOSが終了するまでの間、繰り返し使われることになるだろう)からといってアンロードされるわけではない。という事は、例えば行儀の悪いプログラムが大量に自分のみで使うライブラリをロードしてそのまま終了してしまうと、無意味にライブラリがGlobal Sectionを占有して居座ることになる。これは一種のメモリリークなのであって、勿論プログラミング作法としては間違っているのだが、「間違った操作をされてもシステムに影響を及ぼさない」事はOSとしては重要な要件だから、何らかの対処は必要である。ではここでSectionをPaging可能にするとどうなるか? というと、アクセスが無くなったらPage Fileに退避できるわけで、Page Fileを占有するという問題は残るにせよ、実メモリは空く事になるから、実害はずっと少なくなる。

勿論、Windowsでは全てのメモリがPaging対象になる訳ではない。たとえば7回目で説明したデバイスドライバ周りのIRPとかDPCで呼び出すルーチンをPaging対象に置いたりして、万一それがPage Outしたりした日にはシステムに致命的なダメージが発生する。そういうわけで、WindowsではPoolと呼ばれるメモリ領域が用意されており、今説明したようなCriticalなエリアは全てこのPool上に置かれる。ただPoolにはNon Page PoolとPage Poolがあり...というあたりは上巻P466~に細かく説明されているのでここでは行わないが、まとめてしまえばPaging対象外のメモリが使えるのはSystemとKernel Mode Routinのみで、User Process/Threadが取り扱いできるのは全てPageing対象となるという事だ。この点はVMSから大きく変化した部分だろう。

このPoolという領域は、Windows 9x(というか、Windows 3.1時代)からあったもので、これはWindows NTのインプリメントの際にある程度継承せざるを得なかった機能でもある。恐らくそのインプリメントを考えるときに、Pool=Sectionとするか、分離するかの葛藤があったのではないかと思う。ただ当時のメモリの少なさなどを鑑みて、SectionとPoolを分離することを決めた(結果、OSは複雑化した)わけだが、昨今のメモリ余りの状況を見ると、これが正しかったのかどうか、やや疑問が残るところではある。ただ、そうでなくてもメモリ食いのコンポーネントは多いから(特にVista以降はそれが顕著である)、節約の精神を維持したのは結果として正しかったのかもしれない。