16ビット Windows のメモリ管理アーキテクチャ
OS/2 Museum が解説する 16ビット Windows のメモリ管理は、セグメントベースの設計とオーバーレイマネージャの仕組みを中核とする。GlobalAlloc/GlobalLock/GlobalUnlock API や NE 実行ファイル形式、DLL サポートなど、初期 Windows システムの複雑なメモリ操作メカニズムを詳述する。
16ビット Windows のメモリ管理システムは、初期段階から「高度なオーバーレイマネージャ」として設計されていた。Windows メモリシステムの理解には、この根本的な特性が鍵となる。同システムは、最大 64 KB の連続メモリセグメントを単位とした段階的なメモリ割り当てを採用した。
セグメントベースのメモリ設計
Windows は、NE(New Executable)形式の実行ファイルフォーマットを採用した。このフォーマットは、Multitasking DOS 4.0 で初めて使用され、Windows が拡張した。NE 形式はセグメント指向で、各セグメントはディスク上に個別に保存される。Windows セグメントは、セグメントアドレスではなくハンドルで識別される。ハンドルは 16 ビット値であり、不透明な値として扱われるべきである。
メモリセグメントの管理は、以下の API を通じて実行される。GlobalAlloc API は連続メモリを割り当て、セグメントハンドルを返す。GlobalLock API はセグメントアドレスを返し、セグメントをメモリ内にロックする。GlobalUnlock はセグメントのロックカウントをデクリメントする。
Windows は必要になるまでセグメントの移動や破棄を行わない。ロック解除されたムーバブルセグメントは Windows によって並べ替えられるが、固定セグメントはその場所に留まる。コードセグメントは通常、書き込み不可であるため破棄可能である。一方、データセグメントは通常、書き込み可能であるため破棄不可である。ただし、アプリケーションが内容を再作成できる場合、書き込み可能なデータセグメントが破棄可能となる可能性がある。
DLL と Windows システムアーキテクチャ
Windows DLL は、Windows アプリケーションと同じく NE フォーマット画像である。しかし DLL はアプリケーションではなく、直接実行できず、他のプロセスによって読み込まれてのみ呼び出される。Windows カーネルの大部分は DLL として実装された。これには KERNEL、USER、GDI が含まれる。
DLL は独自のスタックを持たず、常に呼び出し元のスタックで動作する。DLL ほぼすべてが独自のデータセグメントを持つ。DLL では SS(スタックセグメント)は DS(データセグメント)と等しくない。
コンパイラと関数プロローグ / エピローグ
Windows SDK に同梱される CMACROS.INC ファイルは、Windows プロローグとエピローグを仕様書として含む。/Aw コンパイラスイッチは SS ≠ DS を指定するが、関数エントリ時に DS をリロードすべきでないことを示す。/Gw スイッチは遠隔関数(far functions)に対して Windows プロローグとエピローグを生成する。Windows ローダーは、エクスポート関数にパッチを当て、モジュールのデフォルトデータセグメントをロードする。Windows .DEF ファイルの NODATA キーワードは、Windows が関数プロローグにパッチを当てないことを指示する。
Windows はスタックウォークの実行が可能であり、スタックフレームを理解可能な形式で保つことに依存している。
Windows と OS/2 の比較
16ビット Windows と 16ビット OS/2 は、同じ実行フォーマット(NE)を使用した。両者ともセグメントベースのメモリ管理を採用し、Microsoft 同じ開発ツールを使用した。しかし OS/2 は保護モード(protected mode)を用いることで、GlobalLock/GlobalUnlock の必要性を排除した。OS/2 では、セグメントセレクタが同時に Windows ハンドルとセグメントアドレスの等価物として機能した。また OS/2 は、外部呼び出し可能な関数に対して特別なプロローグおよびエピローグコードを必要としなかった。
メモリ診断ツール SHAKER(Windows 1.0 SDK)はセグメントの破棄と移動を強制するために使用された。HEAPWALK は割り当てられたセグメントとその所有者を表示する診断ユーティリティで、利用可能なすべてのメモリを割り当て、1 K 単位で解放できた。Windows 3.0 SDK は依然として Shaker と HeapWalker ツールを同梱していた。Windows 3.1 SDK では、Shaker を Stress ユーティリティに置き換えた。これはリソース不足条件下でのアプリケーション動作をテストするためのツールである。Windows 3.1 は保護モードのみで動作した。
歴史的には、Intel 286 は 1982 年にリリースされ、Windows 開発は 1983 年に開始された。Microsoft C 3.0 は 1985 年にリリースされ、Windows コンパイラスイッチを備えていた。Peter Norton と Paul Yao による『Peter Norton's Windows 3.0 Power Programming Techniques』は 1990 年に発表された。Windows 3.0 は保護モードを導入し、Windows 3.1 は保護モードのみで動作した。
この記事は元記事の事実のみに基づいて自動生成されました。
出典
OS/2 Museum - Win16 Memory Management http://www.os2museum.com/wp/win16-memory-management/ (Peter Norton and Paul Yao『Peter Norton's Windows 3.0 Power Programming Techniques』1990 年発行の報道による)