Windows Debugging之六

來源:互聯網
上載者:User

記憶體管理

===============

記憶體管理器(memory manager)提供了一系列的系統服務來分配(allocate)和釋放(free)虛擬記憶體, 在進程間共用記憶體, 將檔案對應到記憶體, 沖洗(flush)虛擬頁面到磁碟上, 重新擷取關於一系列虛擬頁面的資訊, 修改虛擬頁面的保護設定, 鎖定虛擬頁面到記憶體中.

 

記憶體管理器的兩個主要任務

  • 轉換, 映射進程的虛擬位址空間到實體記憶體上. 這樣, 當一個該進程中的線程在運行時讀寫虛擬位址空間, 正確的實體記憶體會被引用到. 進程的虛擬位址空間的, 存在於實體記憶體上的子集, 叫做working set.
  • 把記憶體中的某些過量使用的內容以頁的形式寫會到磁碟中. 所謂過量使用, 即運行中的線程或者系統程式碼檢視更多的使用實體記憶體而不是當前可用的記憶體內容. 

如同其他的windows可執行服務一樣, 記憶體管理服務允許他們的調用者提供進程控制代碼, 標識出究竟在操縱那個進程的虛擬記憶體. 調用者可以操縱他自己的記憶體, 也可以(在正當許可權下)操縱另一個進程的記憶體. 比如說, 如果一個進程建立了一個子進程, 預設它是有許可權來操縱子進程的虛擬記憶體的. 從那以後, 父進程可以代表子進程分配,釋放, 讀, 寫, 記憶體, 方法是通過調用虛擬記憶體服務, 調用時將子進程的控制代碼當做參數傳遞. 這個特性被子系統使用來管理客戶進程記憶體, 並且這也是實現debugger的關鍵技術, 因為debuggers必須能夠讀和寫被debug的記憶體.

 

記憶體管理器同時還提供相當數量的服務, 比如分配和釋放實體記憶體; 為了給其他的核心態的組件執行direct menory access(DMS)訪問轉換而鎖定實體記憶體中的頁面, 這樣的鎖定如同裝置驅動一樣. 這些函數都已首碼Mm開頭. 另外, 對於記憶體管理器的某些部分並不是限制的很死的, 執行支援函數(the executive support routines)以首碼Ex開頭, 用來從系統堆(分頁的和未分頁的池)上分配和釋放,如同操縱旁側模式的列表一樣.

 

 

系統記憶體池

===============

在系統初始化的時候, 記憶體管理器建立兩種動態大小的記憶體池, 核心態的組件使用這兩種池來分配系統記憶體.

  • 非分頁池---包含系統範圍的虛擬記憶體地址空間, 系統保證該空間內的資料是一直存在實體記憶體中的, 並且保證可以在任意時刻訪問(任何IRQL等級, 任何進程上下文)而不需要遭受分頁錯誤(page fault). 需要非分頁式記憶體是因為有一條規則: 分頁錯誤不能滿足DPC/dispatch水平, 或更高水平的要求.
  • 分頁池--- 在系統空間中可以被分頁, 可以被置換進入和置換出系統的虛擬記憶體地區. 裝置驅動程式不需要從DPC/dispatch水平或者更高的水平上來使用, 所以他們可以使用paged pool(分頁池). 分頁池的記憶體是任意進程上下文都可以訪問的.

這兩種記憶體池都存在於系統地址空間內, 並且被映射到任何一個進程的虛擬位址空間中. 執行者(the executive)提供函數去從這兩種池中分配,釋放記憶體. ExAllocatePool函數就是這些函數之一.

 

有兩種非分頁池: 一種是通用的, 另一種稍微小一些(4個page), 是系統為緊急情況而保留下來的, 所謂緊急情況是指非分頁式記憶體滿了, 並且調用者不能容許分配錯誤的時候. (後一種記憶體池已經不再使用了, 裝置驅動程式可以在低記憶體的情況下, 恰當的寫入. 驅動分析器(driver verifier)讓這種測試很容易.) 單一處理器系統有三種分頁池: 多處理器系統有五種. 擁有多餘一種的記憶體池減小了系統代碼阻塞並發的記憶體池請求的機率, 分頁的和非分頁的記憶體池根據實體記憶體的大小而擁有不同的初始值, 然後慢慢增長. 如果必要的話, 在系統啟動的時候漲到最大值. 你可以覆蓋這些池的初始值, 方法是修改註冊表中的索引值NonPagedPoolSize 和PagedPoolSize, 位置在HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management. 0指的讓系統自動計算尺寸, 或者指定一個尺寸, 單位是byte.

 

地址空間布局

================

預設情況下, 32位Windows 每一個使用者進程可以擁有高達2GB的私人地址空間, 作業系統擁有剩下的2GB. Windows伺服器系列支援啟動時的一個選項, 該選項允許3GB的使用者地址空間. Windows XP和Windows Server 2003包括一個開關(/USERVA), 能允許使用者地址空間在2G和3G之間切換. 這兩種記憶體位址空間的布局詳見.

對於一個地址空間超過2G的進程來說, 鏡像檔案必須要有IMAGE_FILE_LARGE_ADDRESS_AWARE這個標誌位在image header中被設定. 否則, Windows保留額外的地址空間, 所以應用程式不會看到大於0x7FFFFFFF的地址空間. 這個標誌是通過在連結應用程式, 構造可執行程式的時候, 設定連結器標誌

/LARGEADDRESSAWARE來完成的. 該標誌在運行著2G使用者地址空間的作業系統上是沒有作用的. 另外, 如果你啟動了3BG開關, 但是作業系統並不支援3GB使用者地址空間, 那麼系統空間會變成1GB, 使用者地址空間最大還是2G, 即使該設定的標誌位都設定了, 也還是沒有用, 因為作業系統不支援.

 

x86系統地址空間布局

==========================

x86架構在系統空間中有如下的組件:

  • 系統代碼--- 包括作業系統鏡像, HAL, 和啟動作業系統時的裝置驅動程式
  • 系統映射視圖--- 用來映射Win32k.sys, 這個核心態Win32子系統的可載入的部分, 還有它使用的核心態圖形驅動程式.
  • 會話空間--- 用來映射一個使用者會話的具體資訊. 在終端服務安裝了的情況下, Windows server支援多使用者會話. Session working set list描述了會話空間中貯存的和正在使用的部分.
  • 進程頁表和分頁目錄--- 描述虛擬位址映射的資料結構
  • Hyperspace--- 一個特殊的地區用來映射進程的working set list和臨時映射到其他實體記憶體頁, 映射到其他實體記憶體頁的目的是執行諸如將一個free list上的也清零, 或者是使其他頁表的頁表入口無效(比如一個頁被從standy list中移除), 或者在進程建立時建立一個新的進程地址空間.
  • system working set list--- 描述system working set
  • System cache--- 虛擬位址空間被用來映射在系統緩衝(system cache)中開啟的檔案
  • Paged Pool--- 可分頁的系統記憶體堆
  • System page table entries(PTEs)- system PTE使用的pool, 用來映射系統頁(諸如IO space, kernel stacks, memory descriptor lists). 你可以看到有多少系統PTE是available的, 通過檢查記憶體的值: 在效能工具中的Free System Page Table Entries 標籤(counter )
  • Nonpaged Pool --- 非分頁的系統記憶體堆, 通常有兩部分, 一種在系統地地址端, 另一種在系統地址高端.
  • Crash dump information--- 保留下來用來儲存系統崩潰的資訊.
  • HAL usage--- 保留下來的系統記憶體用來存放HAL相關的結構.
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.