天天看點

《windows核心程式設計》讀書筆記——記憶體體系結構

         作業系統所使用的記憶體體系結構是了解作業系統如何運作的關鍵,充分了解系統管理記憶體的方式,往往有助于我們快速而準确地找到了解記憶體問題的實質。

         每個程序都有自己的虛拟位址空間,對32位程序來說,這個位址空間的大小為4GB;對64位程序來說,這個位址空間的大小為16EB。每個程序都有自己專有的位址空間,當程序中的各線程運作時,它們隻能通路屬于該程序的記憶體。線程既看不到屬于其他程序的記憶體,也無法通路它們。雖然應用程式有這麼大的位址空間可用,但是要記住這隻是虛拟的位址空間——不是實體存儲器。

         下圖是32位Windows核心和64位Windows核心的分區資訊。

Partition x86 32-Bit Windows x86 32-Bit Windows with 3 GB   User-Mode x64 64-Bit Windows IA-64 64-Bit Windows
NULL-Pointer Assignment 0x00000000 0x00000000 0x00000000'00000000 0x00000000'00000000
0x0000FFFF 0x0000FFFF 0x00000000'0000FFFF 0x00000000'0000FFFF
User-Mode 0x00010000 0x00010000 0x00000000'00010000 0x00000000'00010000
0x7FFEFFFF 0xBFFEFFFF 0x000007FF'FFFEFFFF 0x000006FB'FFFEFFFF
64-KB Off-Limits 0x7FFF0000 0xBFFF0000 0x000007FF'FFFF0000 0x000006FB'FFFF0000
0x7FFFFFFF 0xBFFFFFFF 0x000007FF'FFFFFFFF 0x000006FB'FFFFFFFF
Kernel-Mode 0x80000000 0xC0000000 0x00000800'00000000 0x000006FC'00000000
0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF'FFFFFFFF

         空指針分區:從0x00000000到0x0000FFFF的閉區間,保留該分區的目的是為了幫助程式員捕獲對空指針的指派。如果程序中的線程試圖讀取或寫入位于這一分區内的記憶體位址,就會引發通路違規。沒有任何辦法可以讓我們配置設定到位于這一位址區間内的虛拟記憶體。

         使用者模式分區:這一分區是程序位址空間的駐地。使用者無法通指針來讀取、寫入或以任何方式通路其他程序的這一分區的資料。(對于LARGEADDRESSAWAR開關這裡不讨論,請參考MSDN)。

         核心模式分區:這一分區是作業系統代碼的駐地。與線程高度、記憶體管理、檔案系統支援、網絡支援以及裝置驅動程式相關的代碼都載入到該分區。駐留在這一分區内的任何東西為所有程序共有。如果一個應用程式試圖讀取或寫入位于這一分區中的記憶體位址,會引發通路違規。

         以下兩段是我根據英語原文的意思,加上我的了解寫出來的,譯著講的很糊塗以緻于會讓人産生誤解。

         當程式預訂一個位址空間區域時,系統在查找可用位址時會確定的起始位址正好是配置設定粒度的整數倍。目前所有CPU使用的粒度都是64K。

         當程式在位址空間區域上預訂一個位址空間塊時,系統會確定塊的大小上調到系統頁面大小的整數倍。不同CPU的頁面大小可能會不一樣,x86和x64系統使用的頁面大小為4KB,而IA-64系統使用的頁面大小為8KB。

         通過使用磁盤上的檔案(頁交換檔案)可以擴充可用實體存儲器的大小,也就是使用虛拟記憶體技術。使用虛拟記憶體會引發換頁錯誤,如果過多的換頁會損害硬碟并且使程式運作變慢。

         當把一個程式位于硬碟上的檔案映像(exe或dll檔案)用作位址空間對應的實體存儲器時,我們稱這個檔案映像為記憶體映射檔案(memory mapped file)。

         實體存儲器頁面的保護屬性清單,另外還有三個特殊的通路保護屬性在這裡沒列出。如果同時給和實體存儲器指定了保護屬性,那麼以實體存儲器指定的為準。

Protection Attribute Description
PAGE_NOACCESS Attempts to read from, write to, or execute code in this page raise an  access violation.
PAGE_READONLY Attempts to write to or execute code in this page raise an access
PAGE_READWRITE Attempts to execute code in this page raise an access violation.
PAGE_EXECUTE Attempts to read or write memory in this page raise an access violation.
PAGE_EXECUTE_READ Attempts to write to memory in this page raise an access violation.
PAGE_EXECUTE_READWRITE There is nothing you can do to this page to raise an access violation.
PAGE_WRITECOPY Attempts to execute code in this page raise an access violation.  Attempts to write to memory in this page cause the system to paging file).
PAGE_EXECUTE_WRITECOPY There is nothing you can do to this region to raise an access violation.  Attempts to write to memory in this page cause the system to give the process  its own private copy of the page (backed by the paging file).

         程序寫時複制不修改原始頁面的保護屬性,隻需要把共享資料複制到自己程序的頁交換檔案空間,再修改程序的頁面表。這些步驟由系統完成。

         記憶體區域類型:

Type Description
Free The region's virtual addresses are not backed by any storage. This  address space is not reserved; the application can reserve a region either at  the shown base address or anywhere within the free region.
Private The region's virtual addresses are backed by the system's paging file.
Image The region's virtual addresses were originally backed by a memory-mapped  image file (such as an .exe or a DLL file). The virtual addresses might not  be backed by the image file anymore. For example, when a global variable in a  module's image is written to, the copy-on-write mechanism backs the specific  page from the paging file instead of the original image file.
Mapped The region's virtual addresses were originally backed by a memory-mapped  data file. The virtual addresses might not be backed by the data file  anymore. For example, a data file might be mapped using copy-on-write protection.  Any writes to the file cause the specific pages to be backed by the paging  file instead of the original data.

         注意Free類型的區塊的基址是無效的,通常為0。

         由于windows将PE檔案映射一程序的虛拟位址空間時,每一段必須另起一頁,而且起始位址必須是系統頁面大小的整數倍,這使PE檔案所需要的虛拟位址空間的大小一般來說要大于檔案本身的大小。

繼續閱讀