仮想記憶
コンピュータのプログラムは命令にせよデータにせよ、必ずメモリー上に置かれていなければCPUが処理することができません。プログラムが大きくなりデータ量も増えてくればそれに応じたサイズのメモリーが必要です。ところが、すべてのプログラムが同じ大きさで同じ量のデータを扱うわけではありませんから、小さなプログラムでは余った使われないメモリーが無駄になってしまいます。昔はメインフレームに限らずハードウェア部品としてのメモリーは非常に高価であったため大きな問題でした。そこで登場したのが仮想記憶と言う考え方の仕組みです。
仮想記憶方式では主記憶装置はハードウェア部品としての実記憶装置とDASD上の補助記憶装置によって構成される論理的な装置として扱われます。MVS上のジョブは一部の例外を除けば実記憶(リアル・ストレージまたはリアル・メモリー)を直接アクセスすることはありません。よってMVSでは単にメモリー、記憶域と言った場合は基本的に仮想記憶(バーチャル・ストレージまたはバーチャル・メモリー)のことを指します。
仮想記憶によって得られるメリットとして大きく以下の2つがあります。
実際のメモリーよりも大きなメモリーを使える。
見かけ上の大きさを増やすことによって、より大きな主記憶装置として利用することができます。
複数のプログラムで効率的に共用できる。
プログラム内の命令やデータは一度に全部がメモリー上に置かれる必要はなく、CPUで処理される部分があれば実行することが出来ます。したがって、CPUが命令を実行する時点で必要な部分だけを実記憶に置いて、それ以外を補助記憶に移しておけば小さな実記憶装置であっても複数のプログラムで同時に利用することが可能になります。
ページングとスワッピング
CPUは実記憶装置しかアクセスできませんから、実際に命令を実行したり演算処理やデータの移動を行うためには命令と対象となるデータは必ず実メモリー上に置かれなければなりません。仮想記憶は一般に実記憶より大きなサイズを持ちます。そのため溢れた内容をどこかにしまっておく必要があります。これが補助記憶でメインフレームではDASD内に作成されているページ・データセットに入れられます。
S/370アーキテクチャーでは、CPUはDATと呼ばれるハードウェア機構によって仮想アドレスのまま命令やデータの場所をアクセスできるようになっています。この時、仮想アドレスで示されたメモリー領域が実際の実記憶上に存在しない場合、CPUはOSに割込みを起こして通知します。MVSはこの割込みを受けて、そのアドレスが示す領域が仮想記憶域として存在するかを調べます。正しい仮想アドレスであればページ・データセットにその内容が退避されているので、DASDからそれを実記憶上に読み込みます。これがページインです。逆に当面CPUが使わない領域はページ・データセットに退避されます。こちらはページアウトです。
このページインとページアウトによって、メモリー領域をCPUがその都度必要とする部分に対応させながら、実記憶と補助記憶間で頻繁にやり取りを行って制御しています。これが「ページング」と呼ばれる仕組みです。MVSでは、やり取りされるメモリー領域を4KBずつの大きさに区切って管理します。この4KBで区切られた領域をページと呼びます。ページングではページ単位に実記憶から補助記憶に書き出され、また逆に補助記憶から実記憶に読み込まれます。
頻繁にアクセスされるページが、その都度DASDから読み込まれるのでは効率が悪いので、優先度が低いジョブが使用している実記憶上のページの集まり(ワーキング・セットと呼ばれます)は、CPUの割込みに依らずMVSが自らまとめてページ・データセットに書き出します。このように、ページ単位ではなくワーキング・セット単位に行われるのが「スワッピング」です。スワッピングは仮想記憶そのもののメカニズムではなく、パフォーマンス制御のために行われるMVSのOSとしての機能です。
なお、MVSのページング制御や割込み制御などを行うモジュールは、ページアウトされてしまうとOSとしての制御ができなくなってしまいます。そこで、OSとしての核になる部分はページアウトされないようになっていて、ページ固定と呼ばれます。
アドレス空間
MVSでは、1つのジョブは1つのアドレス空間の中で動きます。実行するジョブが2つあるとそれぞれが独立したアドレス空間を持ちます。アドレス空間は、プログラムに与えられる一定の大きさを持つ連続したメモリー領域です。メモリーと言ってもあくまでも仮想です。
また、MVSと言う名前は「Multiple Virtual Storage」の略で、複数の仮想空間を並べて制御するためにMVSと名付けられたのです。ここで言うVirtual Storageが仮想アドレス空間です。仮想アドレス空間が複数だからMVSとなったのです。ちなみにMVSの前にはSVSと呼ばれるものもありました。Single、つまり単一の仮想空間では、複数のプログラム(ジョブ)はパーティションと呼ばれる空間内を区分けした区画内で動きます。ジョブ管理とJES2で出てきたイニシエーターは、この区画の考え方の名残です。
アドレス空間は、「メモリー空間」と言い換えて考えてもいいでしょう。Windowsなどではそう呼ばれます。「1つのプロセスには1つの独立したメモリー空間が与えられる」などと解説されたりします。独立しているのがポイントです。ジョブAのプログラムでも、ジョブBのプログラムでも、8000番地は同じ8000番地ですが、お互いの領域がかぶらないのは、それぞれの空間が独立しているからです。この仕組みによって、誤りがあっても他のプログラムのメモリー領域を壊すことがありません。ソフトウェア面におけるシステムの信頼性は大きく向上しました。「行儀の悪いプログラムのおかげでみんなが迷惑する」と言うことは、メインフレームの世界ではすでに1970年代初期には解決していたわけです。
アドレス空間の大きさは、初期のMVSでは16MB(24ビット)、次のMVS/XAでは2GB(31ビット)となりました。何で32ビット使って4GBにしないのか?との疑問をお持ちかも知れません。それには理由があります。
32ビットの先頭の1ビットは、プログラムが16MBまでのメモリーをアクセスできる24ビット・プログラムなのか、それを超えてアクセスできる31ビット・プログラムなのか、を識別するための標識に使われます。そのため、仮想アドレスは残りの31ビットで表現するため最大2GBとなったのです。これは古い24ビット・プログラムも、新しい31ビット・プログラムも、どちらも修正なしでそのまま動かせる互換性のためです。現在のz/OSでも同じです。MVSを始めとするメインフレームOSや、ハードウェアは、この互換性を非常に重要視してきました。故に今でも昔のプログラムが現役で動いているわけです。
現在のz/OSでは16ExaB(64ビット)となっていますが、2GBを超える領域はデータ用に使われプログラム自身はそこでは動きません。64ビットの空間をフルに利用するプログラムは、データベース系の製品など、これから少しずつ出てくるでしょうが、一般のプログラムではそこまでの広大なメモリーはあまり必要とされないと思います。また、アドレス空間の数は最大で32767空間となっていますが、z/OSのデフォルト値では255とされています。
アドレス空間が2GBの大きさを持っていても、そのすべてをプログラムで自由に使える訳ではありません。MVSは空間をOS自身を置く領域、OSがシステムやプログラムを制御するために使う領域、複数のプログラムで共通に使える領域、ユーザー・プログラムを置く領域など、いくつかに区分けして管理します。それぞれの領域の大きさはシステムのパラメーター設定によっても変わってきます。
ユーザー・プログラムが利用できる領域が、「リージョン(REGION)」です(*1)。リージョンは16MBより低い24ビット領域と、16MBより高い31ビット領域の2つに分かれ、それぞれ基本リージョン、拡張リージョンとも呼ばれます。基本リージョンの大きさは、ユーザーのシステム設定によって幅があります(6MB~10MB)が、一般的なユーザーでは8MB程度の大きさを持ちます。拡張リージョンはGBの大きさを持つものの、利用できるのは標準では32MBです。基本リージョン、拡張リージョン共に省略時の解釈値は、ユーザー毎のカスタマイズで変更できます。
*1 正確にはREGION内のPVTと呼ばれる領域です。
アドレッシング・モード
MVSでは、プログラムはアドレッシング・モード(またはアドレス・モード)と呼ばれる、空間内をアクセスできる範囲があります。16MBまでのメモリー域にアクセスできる24ビット・アドレッシング・モード、2GBまでのメモリー域にアクセスできる31ビット・アドレッシング・モード、さらに16ExaBまでのメモリー域にアクセスできる64ビット・アドレッシング・モードです。24ビット・モードを基本モード、31ビット・モードを拡張モードと呼ぶこともあります。
最初のMVSの仮想アドレス空間の大きさは16MBでした。その後MVS/XAになって、仮想アドレス空間が2GBに拡張された時に、旧24ビット・プログラムの互換を保ち、新31ビット・プログラムも同時に動かすために、アドレッシング・モードの考え方が採用されたのです。
Windowsなどのように、32ビットを使用して4GBにしなかったのは、アドレス・ワードの先頭ビットをアドレッシング・モードの識別に使用したためです。CPUは、元々32ビットで、PSWなどもアドレス部は32ビットを持っていたため、それらをそのまま生かして仮想アドレス空間を拡張しました。zアーキテクチャでは、PSWや命令も新たに64ビット対応に変更されたり追加されたりしたので、MVS/XAの時のように63ビットではなく、64ビットをすべて使用してアドレス表現できるようになっています。