天天看點

windows 核心程式設計 (記憶體體系結構)

1、程序的虛拟位址空間

    每個程序都有自己的虛拟位址空間。對于32位程序來說,這個位址空間大小為4G。

    每個程序都有自己的專有位址空間,當程序中的各線程運作時,它們隻能通路屬于該程序的記憶體。線程既看不到屬于其他程序的記憶體,也無法通路它們。

2、虛拟位址空間的分區

    每個程序的虛拟位址空間被劃分成許多分區。

    x86 32位windows系統程序位址空間分區:

            空指針指派分區:    0x00000000 ~ 0x0000FFFF    64k

            使用者模式分區:       0x00010000 ~ 0x7FFEFFFF    2G - 64k - 64k

            64k禁入分區:       0x7FFF0000  ~ 0x7FFFFFFF    64k

            核心模式分區:       0x80000000 ~ 0xFFFFFFFF    2G

3、位址空間中的區域

    當系統建立一個程序并賦予它位址空間時,可用位址空間中的大部分都是閑置的或尚未配置設定的。

    為了使用這部分位址空間,我們必須調用VirtualAlloc來配置設定其中的區域。

    配置設定區域的操作被稱為“預定”(reserving)。

    當應用程式預定空間區域時,系統會確定區域的起始位址正好是配置設定粒度(allocation granularity)(x86平台配置設定粒度大小為64k)

    當應用程式預定位址空間中的一塊區域時,系統會確定區域的大小正好是系統頁面大小的整數倍。(x86系統頁面大小為4k)

    釋放位址空間區域,通過調用VirtualFree函數來完成。

4、給區域調撥實體存儲器

    為了使用所預定的位址空間區域,我們必須配置設定實體存儲器,并将存儲器映射到所預定的區域。這個過程稱為“調撥”(committing)實體存儲器。實體存儲器始終都以頁面為機關來調撥。通過調用VirtualAlloc函數來将實體存儲器調撥給所預定的區域。

    當我們調撥實體存儲器給區域時,并不需要給整個區域都調撥實體存儲器。

    當程式不再需要通路所預定區域中已調撥的實體存儲器時,應該釋放實體存儲器。這個過程稱為“撤銷調撥”(decommitting),通過使用VirtualFree函數來完成。

5、實體存儲器和頁交換檔案

    磁盤上的檔案一般稱為“頁交換檔案”(paging file),其中包含虛拟記憶體,可供任何程序使用。

    為了能夠使用虛拟記憶體,作業系統需要CPU的大力協助。當線程試圖通路存儲器中的一個位元組時,CPU必須知道該位元組是在記憶體中還是在磁盤上。

    最好是把實體存儲器看成是儲存在磁盤(通常是硬碟)上的頁交換檔案中的資料。當應用程式調用VirtualAlloc函數來把實體存儲器調撥給位址空間區域時,該空間實際上是從硬碟上的頁交換檔案配置設定得到的。

    系統中頁交換檔案的大小是決定應用程式可用記憶體總量的最重要的因素,機器實際裝備的記憶體總量對它的影響相對較小。

    系統需要在記憶體和頁交換檔案之間複制頁面的頻率越高,硬碟颠簸(thrash)得越厲害,系統也運作得越慢(颠簸是指作業系統把所有時間都花在頁面檔案和記憶體之間交換資料上,導緻沒有時間運作程式。)通過給計算機添加更多的記憶體,我們可以減少應用程式運作時可能颠簸的次數,提高應用程式性能。

6、不在頁交換檔案中維護的實體存儲器

    當使用者要求執行一個應用程式時,系統會打開該應用程式對應的.exe檔案并計算出應用程式的代碼和資料的大小。然後系統會預定一塊位址空間,并注明與該區域相關聯的實體存儲器就是.exe檔案本身。系統并沒有從頁交換檔案中配置設定空間,而是将.exe檔案的實際内容(或檔案映像)用作程式預定義的位址空間區域。這樣一來,不但載入程式非常快,而且頁交換檔案也可以保持一個合理的大小。

    當把一個程式位于硬碟上的檔案映像(即一個.exe或DLL檔案)用作位址空間區域對應的實體存儲器時,我們稱這個檔案映像為“記憶體映射檔案”。

7、頁面保護屬性

    記憶體頁面保護屬性分為讀,寫,執行等基本屬性。

    這裡還存在一種"copy on write"(寫時複制)屬性,它們存在目的是為了節省記憶體和頁交換檔案的使用。

    windows支援一種機制,允許兩個或兩個以上的程序共享同一塊存儲器。它讓所有的應用程式執行個體隻能讀取其中的資料或執行得代碼。如果某個應用程式修改并寫入一個存儲頁,那麼這等于修改了其他執行個體正在使用的存儲頁,最終導緻混亂。為了避免混亂,作業系統會給共享的存儲頁指定寫時複制屬性。當系統把一個.exe或.dll映射到一個位址空間的時候,系統會計算有多少頁面是可寫的。然後系統會從頁交換檔案中配置設定存儲空間來容納這些可寫頁面。除非應用程式正的寫入可寫頁面,否則不會用到頁交換檔案中的存儲器。

8、資料對齊

    隻有當通路已對齊的資料時,CPU的執行效率才最高。

    把(資料的位址) %(取模)(資料所占空間的大小),如果結果為0,那麼資料是對齊的。

    如果CPU要通路的資料沒有對齊,那麼會有兩種可能。第一種可能是CPU會引發一個異常,另一種可能是CPU會通過多次通路已對齊的記憶體,來取得整個錯誤資料。

    x86 CPU的EFLAGS寄存器内有一個特殊的标志位,AC(alignment check 對齊檢查)。預設情況下, 這個标志位在第一次給CPU通電時被清零。如果标志為0,那麼CPU會自動執行必要的操作來通路錯位資料。但是如果該标志位為1,那麼一旦程式試圖通路錯位資料,CPU就會觸發INT 17H中斷。

    x86 版本的windows從來不會改變這個标志,是以應用程式在x86處理器上運作時,絕對不會發生資料錯位的異常。