天天看點

《windows 核心程式設計》 -探索虛拟記憶體

14.1 系統資訊

作業系統中有許多值 是由系統所運作的主機所決定的。如果頁面大小和配置設定粒度等。我們決對不應該在代碼中将這些值寫死。 此函數得到系統資訊VOID GetSystemInfo(LPSYSTEM_INFO ps) 如果想得到機器中與處理器有關的詳細資訊可以調用GetLogicalProcesorInfomation函數 為了讓32位應用程式在64位版本的Windows運作,Microsoft提供了一個稱為windows 32 bit On Windows 64 的模拟層又稱為WOW。當32 位應用程式通過WOW64運作時,GetSystemInfo的傳回值在64位應用程式可能會有所不同。如果想知道程序是否在WOW64運作可以調用下面的函數 BOOL IsWow64Process(HANDLE hProcess PBOOL pbWow64Process); 隻有32位程式在WOW64上運作時該布爾值才會被設為TRUE,在這種情況下我們需要調用void GetNativeSystemInfo來取得原來的SYSTEM_INFO結構。

14.1 虛拟記憶體狀态

Windows函數GlobalMemoryStatus可以用來取得目前記憶體動态資訊 如果預計應用程式會在裝有4GB的記憶體的機器上運作,或者頁交換檔案的大小可能會大于4GB,那麼就應該調用GlobalMemoryStatusEx函數。

14.3 NUMA機器中的記憶體管理

NUMA(Non-Uniform Memory Acess),非統一記憶體通路機器中的CPU既能通路自己節點的記憶體,也能通路其它節點的記憶體。但是,對CPU來說,通路自己節點的記憶體比方通路外節點的記憶體要快的多。在預設情況下,當線程調撥實體存儲器時,作業系統會盡量用CPu自己節點的記憶體來支援實體存儲器,以提高記憶體通路的性能。但是,如果沒有足夠的記憶體,那麼Windows也會使用其它結點的記憶體來支援實體存儲器。 在調用GlobalMemoryStatusEx函數時,在ullAvailPhys參數中傳回的值是所有節點可用記憶體總量。如果要知道某個特定NUMA節點的記憶體數量,那麼可以調用下面的函數 BOOL GetNumaAvailableMemoryNode(UCHAR uNode, //辨別節點         PULONGLONG pulAvailableBytes);  //用來傳回該節點可用的記憶體總量。 隻需要調用GetNumaProcessorNode函數就可以得到一個CPU駐留在哪個NUMA 節點中。 可以用GetNumaHighestNodeNumber(PULONG pulHighestNodeNumber);得到系統中節點的總數。 對于任何一個指定的節點來說,他的值價于0和pulHighestNodeNumber參數所指變量值之間。我們可以調用下面的函數來得到駐留在某個節點中的CPU清單; BOOL GetNumaNodeProcessorMark(UCHAR uNode,     PULONGLONG pulProcessorMask);

示例:

沒有哪個成員能表示實體存儲器的數量。我們把一個程序的位址空間中被儲存在記憶體裡的那些頁面稱為它的工作集 對于一個進來來說我們可能通過GetProcessMemoryInfo來得到正在使用
知道程序工作集大小是極其有用的,因為它可以告訴我們一旦程式到達穩定狀态會需要多少記憶體,将應用程式的工作集減少到最小有助于提高程式性能

14.4 确定位址空間狀态

下面函數查詢與位址空間中記憶體位址有關的特定資訊(比如大小、存儲器類型、保護屬性等)。 <code>SIZE_T WINAPI VirtualQuery(   __in_opt  LPCVOID lpAddress,   __out     PMEMORY_BASIC_INFORMATION lpBuffer,   __in      SIZE_T dwLength );</code> <code>下面函數可以查詢另一個程序的與記憶體位址相關的特定資訊</code>

成員 描述 BaseAddress 它的值等于将參數pvAddress向下取整到頁面的大小 AllocationBase 辨別出區域的基位址,該區域包含參數pvAddress 所指定的位址 AllocationProtect 辨別出最開始預訂區域時為該區域指定的保護屬性 RegionSize 辨別出區域大小(位元組),區域起始位址為BaseAddress區域中的所有頁面擁有相同的保護屬性、狀态及類型 State 辨別出區域中的頁面狀态 Proctect 針對所有相鄰頁面 Type 辨別出區域中頁面類型  

繼續閱讀