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