【基本資料】

書名:Windows 記憶體管理 - 系統篇
出版:旗標 1993.06
ISBN:957-717-050-1
頁數:3 章,507 頁
定價:NT$ 450.0



【自序】


物有本末 事有始終 知所先後 則近道矣


1992 年是等待、猶豫、觀望的一年 -- 對應用軟體廠商而言。IBM 推出了 OS/2 2.0,真正的 32 位元個人電腦作業系統;Windows NT 則是樓梯嘎嘎響,不見人下來,推出日期一延再延。念舊的人懷念他喝得很習慣的咖啡,也懷念他用的很習慣的DOS。16 位元與 32 位元作業系統之爭,以及 32 位元與 32 位元作業系統之爭,終於邁進了 1993 年。

是的,這真是個突飛猛進的時代,作業系統之中的核心 --- 定址能力與記憶體管理 -- 變化尤大,記憶體的單位已經由 KB 進入到 MB 甚至到 GB 了。

自「虛擬記憶體」、「新一代 PC 環境之記憶體管理與多工」這兩本書以降,我一直在探討 PC 軟硬體環境在記憶體方面對程式寫作的束縛,以及運應之道。雖然「DOS 記憶體之寶貴一如東京房地產 (或者現在您可以說台北的房地產)」這樣的情況在Windows 環境下不復存在,但在 640KB 突破之後卻隱隱另有一個 64KB 的系統限制。尤其在發展大型軟體的過程中,這 64KB 最後又變成了程式員的黑色夢靨,讓人頗有「未到千般恨不消,到時原來無一物」之歎。

對於喜歡探究系統內部祕密的人 (我就是其中之一),「Windows 記憶體管理-系統篇」的刨根究底能夠滿足您對 Windows 作業系統如何定址、如何管理記憶體的好奇心。這些知識或可成為更進一步了解保護模式作業系統如 OS/2 2.0 或 Windows NT 的紮實基礎。如果想運用在程式設計或環境的效率調整上,另一本書「Windows 記憶體管理-應用篇」有許多我個人在發展大型軟體的過程中獲得的經驗。並不是每一個人都可能在 Windows 環境下受到記憶體的困擾,但如果您參與大型軟體發展計劃,這個挑戰恐怕跑不掉。

就像 C runtime 程式庫一樣,Windows 內部的記憶體管理體系也可以在應用程式發展過程中完全透明化 (換句話說不知道這些知識您還是可以寫一般應用程式),但如果您很嚴肅地要學好 Windows 這個作業系統以及更高級的程式設計技巧,掌握基礎知識非常非常必要。

再沒有什麼比得上我自讀者口中得知我的書對他們有幫助時,心中的快樂了。

侯俊傑 (J.J.Hou) 1993/04/28 于新竹


[本書架構]

我曾經在「虛擬記憶體 : 觀念、設計與實作」中說過 :

如果說硬體是電腦的軀體,軟體是電腦的靈魂,那麼記憶體可以說是電腦的大腦所在位置了。所有人類的思維都在大腦中進行,而所有的軟體程式碼以及軟體所需要的資料都必需在記憶體中運算並貯存。這可以解釋記憶體之於電腦的重要性。

我也曾經在「新一代 PC 環境之記憶體管理與多工」一書中說過 :
記憶體是電腦系統中最重要的資源,甚至有一派論者主張 CPU 不是電腦的中心,記憶體才是 ! (這令人想起哥白尼的學說。) 記憶體的定址必需由 CPU 完成,而CPU 的多工能力必需倚賴記憶體管理程式的協助。所以多工和記憶體這兩大主題正探索到電腦最深處的靈魂所在。

這一次,再延續「記憶體管理」這個主題,我們把視野伸展到 Windows。

想要以最佳方式運用記憶體,可以從三個方向努力 :

一 終端使用者依據本身機器上的硬體配備,善加運用各種設備驅動程式或公用程式,對環境作校調 (tuning) 的工作。

二 程式員了解系統的內部動作,並在設計程式時配合之。例如適當的節區屬性,適當的模組、堆疊 (stack)、堆積 (heap) 大小,以及避免違反「分頁式虛擬記憶體」處理原則。

三 程式員以程式技巧突破系統的限制,例如 64KB AUTO 資料節區的限制、8192 個handle 的限制、超越 64K 的記憶體動態配置 ... 等等。

為能完整顧慮到這三點,「Windows 記憶體管理」從兩個方向出發,互為經緯。一個方向是系統本身的原則性探討,包括 Windows 各種執行模式下記憶體的運用、CPU 保護模式定址方式、多工環境下作業系統如何樽節對記憶體的需求、Windows 3.x 中的 64KB 資料節區限制、8192 個 handle 的限制、DPMI 記憶體/DOS 記憶體、Windows NT 記憶體管理,這一個方向正是本書的主題;第二個方向從系統效率的校調以及應用程式的設計技巧著手,包括 Windows 在記憶體和多工作業方面相關參數的調整、運用巨大的記憶體區塊、讓 EDIT、LISTBOX 的容量達到最大、利用 CODE 節區以及 Resource 節區減輕資料量的負擔、建立巨大的多維陣列 ... 等等,這些題目構成「Windows 記憶體管理-應用篇」。

不論您是不是具備學院派資訊科系的背景,不論您是否修過作業系統課程,這些活生生的、看得到摸得到 (您一定要原諒我用這麼生動的形容詞) 的程式輸出結果一定都可以讓您發現,教科書中的作業系統記憶體管理並不如想像中那麼遙不可及。

第零章 - 基礎工具與技巧

為了把注意力放在本書的主題上,我不想花太多時間來設計一個漂亮的輸出畫面。全書許多範例程式採用一個類似傳統 printf() 的輸出模組,其內部最後是藉助 MessageBox 和 NotePad 來完成文字的輸出。這一章介紹 printf 模組的設計方法。 本書已進入 Windows KERNEL 模組的核心。我們彷彿在地雷處處的區域探險。不僅程式寫作的困難度提高,程式執行的結果也很難驗證。因此本章特別介紹 Microsoft CodeView Debugger for Windows 的功能以及使用方式。Windows SDK 中還有一個工具 "Heap Walker",可以觀察各式各樣的記憶體內容,本章對這個工具也有許多介紹。

第一章 - Windows 定址模式與記憶體管理

這一章的篇幅很多,介紹的全是最基礎最重要的保護模式觀念。我們一定得從保護模式定址開始,了解 selector、descriptor、paging、flat model,然後我們才能夠討論「分頁式虛擬記憶體管理」是怎麼一回事,這其中關係到線性位址的格式與意義,以及雙層表格 (Page Directory 和 Page Table) 轉換。對於分頁 (paging) 動作有了了解之後,我們才能夠探究所謂的 segment 屬性 (FIX、MOVEABLE、DISCARDABLE) 的意義以及系統的反應。

本章包含五個程式實例 :

CR3.386 - 為了觀察 Page Directory,我們需要 CR3 系統暫存器的值,這必須利用虛擬裝置驅動程式 (VxD) 才辦得到。CR3.386 負責這件事情,因此我也會介紹一些關於 VxD 的設計觀念。

PAGEDIR - 顯示 Page Directory 的內容。
PAGETAB - 顯示 Page Table 的內容。
PHYSADR - 可以顯示某一節區所含之各個 page 的實體位址及資訊。
SHOWVXD - 顯示您的系統中所有已經安裝好的 VxD 名稱和進入點。

這個例子有助於我們多了解「無處不至、無所不能」的 VxD。

第二章 - Windows 系統資源與限制

Windows 雖然已經突破 DOS 的 640K 限制,但卻還有一個 64KB 資料節區的限制尚未突破。任何程式在 Windows 3.x 下引發 "automatic data segment plus heap over 64K" 的聯結錯誤時,只有死路一條。本章詳細探討AUTO 資料節區的結構,並以一個 DDSVIEW 程式觀察其實際內容,可以做為發展應用程式時的重要參考 (您可以據此決定模組定義檔中的 stack 大小與local heap 大小)。
另一個 Windows 程式限制是 8192 個 handle,起因是 Windows 整個系統共用一個 LDT,而 CPU 保護模式中一個 LDT 只有 8192 個 Descriptor。本章的 MEMWIN 程式驗證了這個缺點。至於解決之道,請參考「Windows 記憶體管理 - 應用篇」。

本章包含五個程式實例 :

FSRMON - 顯示所謂的 FSR (系統資源),本程式採用數種不同的方法來觀察 USER 和GDI 模組的 AUTO 節區剩餘空間,獲得的結果正可做一比較。

DDSVIEW - 尋幽訪勝 64K AUTO 節區。

MEMDOS - 這是一個 DOS 程式,將所有的自由記憶體配置光。這個程式是用來與MEMWIN 做一比較。

MEMWIN - 突顯 Windows 的 handle 個數限制。

SEGATTR - 顯示不同屬性的節區依然可能存在於同一個 page 中。

第三章 - Windows 3.1 ToolHelp 模組

在 Windows 3.1 的新功能中,ToolHelp 是份量極重的一個模組。ToolHelp 可以滿足具有窺視系統祕密之欲望的人,對除錯工具發展者亦會有很大的幫助。ToolHelp 的九大類別 API 中,有的可以觀察系統資訊,有的可以觀察 task list、或是 global list、或是 class list ...,還有的可以用來協助設計除錯工具、攔截 CPU Fault。
這一章的另一個主題是探討三個在作業系統層面上十分重要的名詞 : module、task、以及 instance。以及所謂的 Module Database、
Task Database。

本章提供四個實例 :

DDSWALK : 這是第二章 DDSVIEW 程式的 ToolHelp 版本。

GHEAP : 觀察 Global Heap 中所有的區塊 (類似 Heap Walker 功能) 及其內容。

SYSMON : 觀察各種系統資訊,包括 Task List、Class List、Module List ...。

ERRTRAP : 示範一些會引起系統錯誤的程式動作 (例如 Divided by Zero、Infinite Loop),並註冊一個 Notification Callback 和一個 Interrupt Handler,攔截系統的錯誤訊息。


f311.jpg (17296 bytes)