推动Windows的限制:虚拟内存
在我推出Windows的限制后,我討論了物理內存限制,包括由許可,實現和驅動程序兼容性施加的限制。這是整個推動限制系列的索引。雖然他們可以獨立存在,但他們認為你是按順序閱讀的。
推動Windows的限制:物理內存
推動Windows的限制:虛擬內存
推動Windows的限制:分頁和非分頁池
推動Windows的限制:進程和線程
推動Windows的限制:把手
推動Windows的限制:USER和GDI對象 - 第1部分
推動Windows的限制:USER和GDI對象 - 第2部分
這一次我把注意力轉移到另一個基本的資源,虛擬內存。虛擬內存將程序的內存視圖從系統的物理內存中分離出來,因此操作系統決定何時以及如何將程序的代碼和數據存儲在物理內存中以及何時將其存儲在文件中。虛擬內存的主要優點是它允許更多的進程并行執行,否則可能適合物理內存。
盡管虛擬內存具有與物理內存限制相關的限制,但是虛擬內存具有來自不同來源的限制,并且根據消費者而不同。例如,虛擬內存限制適用于運行應用程序,操作系統和整個系統的單個進程。記住這一點很重要,就像虛名一樣,虛擬內存與物理內存沒有直接的聯系。Windows為文件高速緩存分配一定數量的虛擬內存并不指定它在物理內存中實際緩存了多少文件數據;?它可以是從沒有到超過可通過虛擬內存尋址的數量的任何數量。
處理地址空間
每個進程都有自己的虛擬內存,稱為地址空間,將其執行的代碼映射到代碼引用和處理的數據中。32位進程使用32位虛擬內存地址指針,它為32位進程可以處理的虛擬內存量創建4GB(2 ^ 32)的絕對上限。但是,操作系統可以在不改變地址空間的情況下引用自己的代碼和數據以及當前正在執行的進程的代碼和數據,使得在每個進程的地址空間中都可以看到它的虛擬內存。默認情況下,Windows的32位版本在系統和活動進程之間平均分配進程地址空間,每個進程限制為2GB:
?
應用程序可能會使用堆API,.NET垃圾收集器或C運行時malloc庫來分配虛擬內存,但是所有這些都依賴于VirtualAlloc?API。當應用程序耗盡地址空間時,VirtualAlloc以及因此分層的內存管理器將返回錯誤(由NULL地址表示)。為了演示各種Windows限制,我為第4版Windows內部版本編寫的Testlimit實用程序重復調用VirtualAlloc,直到指定-r開關時出現錯誤。因此,當您在32位Windows上運行32位版本的Testlimit時,它將占用整個2GB的地址空間:
2010 MB不是2GB,但是Testlimit的其他代碼和數據,包括它的可執行文件和系統DLL,都是不同的。您可以通過在Process Explorer中查看其虛擬大小來查看其消耗的地址空間總量:
一些應用程序(如SQL Server和Active Directory)可以管理大型數據結構,并且可以同時將更多內容加載到其地址空間中,從而實現更好的性能。因此,Windows NT 4 SP3引入了啟動選項/ 3GB,通過將系統地址空間的大小減少到1GB,可以提供3GB的4GB地址空間,而Windows XP和Windows Server 2003引入了/ userva選項,在2GB和3GB之間任意分割:
?
然而,要利用2GB行以上的地址空間,進程必須在其可執行映像中設置“可識別大地址空間”標志。訪問額外的虛擬內存是選擇加入,因為有些應用程序已經假定他們會給地址空間最多2GB。由于引用地址低于2GB的指針的高位始終為零,因此它們將使用指針中的高位作為自己數據的標志,并在引用數據之前將其清除。如果他們運行一個3GB的地址空間,他們會無意中截斷值大于2GB的指針,導致程序錯誤,包括可能的數據損壞。
Windows中的所有Microsoft服務器產品和數據密集型可執行文件均標有大地址空間感知標志,包括Chkdsk.exe,Lsass.exe(在域控制器上承載Active Directory服務),Smss.exe(會話管理器)以及Esentutl.exe(Active Directory Jet數據庫修復工具)。您可以看到圖像是否帶有Visual Studio自帶的Dumpbin實用程序的標志:
Testlimit也被標記為可以識別大地址,所以如果用3GB的用戶地址空間啟動時用-r開關運行它,你會看到如下所示:
由于64位Windows上的地址空間遠遠大于4GB,我將稍后介紹,Windows可以為32位進程提供最多4GB的地址空間,并將剩下的空間用于操作系統的虛擬內存。如果您在64位Windows上運行Testlimit,則會看到它占用整個32位可尋址地址空間:
64位進程使用64位指針,所以它們的理論最大地址空間是16艾字節(2 ^ 64)。但是,Windows不會在活動進程和系統之間平均分配地址空間,而是在進程的地址空間中定義一個區域,為系統內存資源(如系統頁表項(PTE)),文件緩存以及分頁和非分頁池。
進程地址空間的大小在IA64和x64版本的Windows上是不同的,通過平衡哪些應用程序需要的內存開銷(頁表頁面和轉換后備緩沖區 - TLB - 項目)來支持地址空間。在x64上,這是8192GB(8TB),在IA64上是7168GB(7TB - 與x64的1TB差距來自于IA64頂層頁面目錄為Wow64映射保留插槽的事實)。在Windows的IA64和x64版本上,各種資源地址空間區域的大小為128GB(例如,非頁面緩沖池分配有128GB的地址空間),除了分配1TB的文件緩存外。因此,64位進程的地址空間看起來像這樣:
這個數字并不是按比例繪制的,因為即使是8TB,更小的128GB,也不會是一條小條子。只要說像我們的宇宙那樣,在64位進程的地址空間中就有很多空虛。
當您使用-r開關在64位Windows上運行64位版本的Testlimit(Testlimit64)時,您將看到它消耗8TB,這是它可以管理的地址空間部分的大小:
?
承諾的內存
Testlimit的-r開關有保留虛擬內存,但實際上沒有提交。保留的虛擬內存不能實際存儲數據或代碼,但應用程序有時使用保留來創建大塊虛擬內存,然后根據需要提交,以確保提交的內存在地址空間中連續。當一個進程提交一個虛擬內存區域時,操作系統保證它可以將進程存儲在內存中的所有數據保存在物理內存或磁盤上。這意味著一個進程可能會遇到另一個限制:提交限制。
正如您對提交保證的描述所期望的那樣,提交限制是物理內存和分頁文件大小的總和。實際上,由于操作系統為了自己的使用而保留物理內存的一部分,所以并不是所有的物理內存都會占用這個提交限制。所有活動進程的已提交虛擬內存量(稱為當前提交費用)不能超過系統提交限制。達到提交限制時,提交內存的虛擬分配失敗。這意味著即使是一個標準的32位進程也可能會在虛擬內存分配失敗之前達到2GB的地址空間限制。
當前的提交費用和提交限制由Process Explorer在Commit Charge部分的System Information窗口中和Commit History條形圖和圖表中進行跟蹤:
??
在Vista和Windows Server 2008之前的任務管理器顯示了類似的當前提交費用和限制,但在其圖中調用當前提交費用“PF Usage”:
在Vista和Server 2008上,任務管理器不顯示提交費用圖,并使用“頁面文件”標記當前提交費用和限制值(盡管即使沒有分頁文件,它們也將是非零值) :
您可以通過使用-m開關運行Testlimit來強調提交限制,它指示它分配提交的內存。Testlimit的32位版本在達到提交限制之前可能達到也可能不達到其地址空間限制,具體取決于物理內存的大小,分頁文件的大小以及運行時的當前提交費用。如果您正在運行32位Windows,并希望看到系統在達到提交限制時的行為,只需運行Testlimit的多個實例,直到達到提交限制,然后再耗盡其地址空間。
請注意,默認情況下,頁面文件被配置為增長,這意味著當提交費用接近它時,提交限制將會增長。即使分頁文件達到最大尺寸時,Windows仍然保留一些內存,其內部調整以及緩存數據的應用程序可能會釋放更多內存。Testlimit預期這一點,當它達到提交限制時,它會休眠幾秒鐘,然后嘗試分配更多的內存,無限期地重復,直到你終止它。
如果運行64位版本的Testlimit,幾乎可以確定在耗盡地址空間之前會達到提交限制,除非物理內存和分頁文件總和超過8TB(如前所述,這是64位版本的大小) bit應用程序可訪問的地址空間。以下是在我的8GB系統上運行的64位Testlimit的部分輸出(我指定了100MB的分配大小以使其更快地泄漏):
?
以下是Testlimit暫停后允許分頁文件增長的步驟提交歷史記錄圖:
當系統虛擬內存不足時,應用程序可能會失敗,嘗試執行例行操作時可能會遇到奇怪的錯誤消息。但是在大多數情況下,Windows將能夠為您呈現低內存分辨率對話框,就像我在運行此測試時所做的那樣:
退出Testlimit后,當內存管理器截斷它創建的分頁文件的尾部以適應Testlimit的極端提交請求時,提交限制可能會再次下降。在這里,Process Explorer顯示當前限制遠低于Testlimit運行時達到的峰值:
處理提交的內存
由于提交限制是一個全局資源,其消耗可能導致性能下降,應用程序故障甚至系統故障,所以一個自然的問題是“提交的代價是多少”。要準確回答這個問題,您需要了解應用程序可以分配的不同類型的虛擬內存。
并非所有進程分配的虛擬內存都計入提交限制。如你所見,保留的虛擬內存不會。在磁盤上表示文件的虛擬內存稱為文件映射視圖,除非應用程序要求寫入時復制語義,否則也不會計入限制,因為Windows可以放棄與物理內存中與視圖關聯的任何數據,然后從文件中檢索它。Testlimit的地址空間中映射其可執行文件和系統DLL映像的虛擬內存因此不計入提交限制。有兩種類型的進程虛擬內存可以計入提交限制:private和pagefile-backed。
私有虛擬內存是垃圾收集器堆,本地堆和語言分配器的基礎。它被稱為私有的,因為根據定義,它不能在進程間共享。出于這個原因,很容易歸因于一個進程,而Windows使用Private Bytes性能計數器跟蹤它的使用情況。Process Explorer在“進程屬性”對話框的“性能”頁面的“虛擬內存”部分的“專用字節”列中顯示進程專用字節的使用情況,并以圖形形式顯示在進程屬性對話框的“性能圖表”頁面上。這是Testlimit64達到提交限制時的樣子:
頁面文件支持的虛擬內存很難歸類,因為它可以在進程之間共享。事實上,沒有特定于流程的計數器,您可以查看流程分配或引用的數量。當你用-s開關運行Testlimit時,它會分配頁面文件支持的虛擬內存,直到達到提交限制,但是即使在超過29GB的提交之后,進程的虛擬內存統計信息也不會提供任何指示負責:
出于這個原因,我在前面添加了-l開關。進程必須打開一個頁面文件支持的虛擬內存對象(稱為段),以便在其地址空間中創建頁面文件支持的虛擬內存的映射。盡管Windows保留了現有的虛擬內存,即使應用程序關閉了由它創建的部分的句柄,大多數應用程序仍然保持句柄處于打開狀態。-l開關打印進程已打開的頁面文件支持部分的分配大小。以下是Testlimit在使用-s開關運行后打開的句柄的部分輸出:
你可以看到Testlimit在1MB的塊中分配了頁面文件支持的內存,如果你總結了所有打開的部分的大小,你會發現至少有一個進程貢獻了大量的費用。
我應該做多大的分頁文件?
也許與虛擬內存相關的最常見的問題之一是,我應該使頁面文件有多大?網絡上和報刊雜志上都沒有可笑的建議,甚至微軟也發布了誤導性的建議。幾乎所有的建議都是基于將RAM大小乘以一定的因子,通用值為1.2,1.5和2.現在您已經理解了分頁文件在定義系統的提交限制以及進程如何對提交計費作出貢獻的過程中所起的作用,你已經準備好了解這些公式是多么的無用了。
由于提交限制設置了可以通過運行進程同時分配多少私有文件和頁面文件支持的虛擬內存的上限,因此合理調整頁面文件大小的唯一方法是知道您喜歡的程序的最大總交付費用同時運行。如果提交限制小于該數字,則程序將無法分配所需的虛擬內存,并且無法正常運行。
那么您如何知道您的工作負載需要多少費用?您可能已經注意到在屏幕截圖中,Windows跟蹤該號碼,Process Explorer顯示它:峰值提交費用。為了最佳地調整分頁文件的大小,您應該啟動所有同時運行的應用程序,加載典型數據集,然后記下提交電荷峰值(或者在知道最大負載的一段時間后查看此值) 。將頁面文件的最小值設置為該值減去系統中RAM的數量(如果該值為負值,則選擇最小大小以允許配置的崩潰轉儲類型)。如果您希望有一些潛在的大型提交需求的呼吸空間,請將該數字設置為最大值的兩倍。
有些人覺得沒有分頁文件導致更好的性能,但一般來說,有一個分頁文件意味著Windows可以寫修改列表中的頁面(代表那些沒有被主動訪問,但沒有被保存到磁盤的頁面)分頁文件,從而使該內存可用于更有用的目的(進程或文件緩存)。因此,雖然可能有一些工作負載在沒有分頁文件的情況下執行得更好,但一般來說,這意味著更多的可用內存可用于系統(不必介意,Windows將無法編寫內核崩潰轉儲,而無需分頁文件大小足以容納他們)。
分頁文件配置是在系統屬性,您可以通過在運行對話框中鍵入“sysdm.cpl”,單擊高級選項卡,單擊性能選項按鈕,單擊高級選項卡(這是真正的高級) ,然后點擊更改按鈕:
您會注意到,默認配置是為Windows自動管理頁面文件大小。當在Windows XP和Server 2003上設置該選項時,Windows將創建一個頁面文件,如果RAM小于1GB,則該文件的最小大小是RAM的1.5倍;如果大于1GB,則RAM大小是RAM的三倍。在Windows Vista和Server 2008上,最小值應該足夠大以容納內核內存崩潰轉儲,并且是RAM加上300MB或1GB,以較大者為準。最大值是RAM大小的三倍或4GB,以較大者為準。這就解釋了為什么我的8GB 64位系統的峰值提交在其中一個屏幕截圖中顯示的是32GB。我猜那些編寫代碼的人從我提到的其中一本雜志上得到了他們的指導!
與虛擬內存相關的幾個最終限制是Windows支持的頁面文件的最大大小和數量。32位Windows的最大頁面文件大小為16TB(如果由于某種原因以非PAE模式運行,則為4GB),而64位Windows可以在x64上具有高達16TB的頁面文件,IA64上的頁面大小為32TB。Windows 8 ARM的最大分頁文件大小是4GB。對于所有版本,Windows最多支持16個分頁文件,每個文件必須位于單獨的卷上。
版 | 限制x86不帶PAE | 限制x86 w / PAE | 限制在ARM上 | 限制在x64 | 限制IA64 |
Windows 7的 | 4GB | 16 TB | 16 TB | ? | |
Windows 8 | ? | 16 TB | 4GB | 16 TB | ? |
Windows Server 2008 R2 | ? | ? | 16 TB | 32 TB | |
Windows Server 2012 | ? | ? | ? | 16 TB | ? |
總結
以上是生活随笔為你收集整理的推动Windows的限制:虚拟内存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Silicon C8051F340之GP
- 下一篇: Zookeeper C API 基本常量