推动Windows的限制:USER和GDI对象 - 第2部分
上次,我介紹了限制以及如何度量兩個關鍵窗口管理器資源USER對象之一的使用情況。這一次,我將介紹其他關鍵資源,GDI對象。與往常一樣,我建議您在此之前閱讀以前的帖子,因為與USER和GDI資源相關的一些限制是基于我所介紹的限制。這里是我的另一個推動Windows的限制職位的完整索引:
推動Windows的限制:物理內存
推動Windows的限制:虛擬內存
推動Windows的限制:分頁和非分頁池
推動Windows的限制:進程和線程
推動Windows的限制:把手
推動Windows的限制:USER和GDI對象 - 第1部分
GDI對象
GDI對象表示圖形設備接口資源,如字體,位圖,畫筆,筆和設備上下文(繪圖表面)。與USER對象一樣,窗口管理器將進程限制為至多10,000個GDI對象,您可以使用-g開關使用Testlimit來驗證該對象:
您可以在其Process Explorer進程屬性對話框的Performance頁面上查看單個進程的GDI對象使用情況,并將GDI對象列添加到Process Explorer以觀察跨進程的GDI對象使用情況:
與USER對象一樣,16位互操作性意味著USER對象具有16位標識符,每個會話限制為65,535個標識符。當Testlimit達到Windows Vista 64位系統上的限制時,出現桌面:
請注意它所在的左下角的“開始”按鈕,但屏幕頂部的任務欄的其余部分。桌面變黑了,邊欄已經失去了大部分的顏色。你的里程可能會有所不同,但你可以看到奇怪的事情開始發生,可能使得不可能以可靠的方式與桌面交互。以下是按下“開始”按鈕時顯示切換的內容:
與USER對象不同,GDI對象不是從桌面堆分配的;?相反,在沒有安裝終端服務的Windows XP和Windows Server 2003系統上,它們將從常規分頁池中分配;?在從會話會話池中分配的所有其他系統上。?
內核調試器的“!vm 4”命令會轉儲一般虛擬內存信息,包括輸出結尾的會話信息。在Windows XP系統上,它顯示會話分頁池未被使用:
在沒有終端服務的Windows Server 2003系統上,輸出類似:
因此,這些系統上的GDI對象內存限制是頁面緩沖池的限制,正如我以前的文章“?推動Windows的限制:分頁和非分頁池”所述。但是,如果終端服務安裝在相同的Windows Server 2003系統上,則可以從非零會話池中看到GDI對象來自會話池:
上述輸出中的!vm 4命令還顯示會話分頁池最大值和會話池大小,但會話分頁池最大值和會話空間大小在Windows Vista及更高版本上不顯示,因為它們是可變的。這些系統上的會話分頁池使用率受其可增長的地址空間量或系統提交限制(以較小者為準)的上限限制。以下是Windows 7系統上命令的輸出,顯示會話中當前會話分頁池的使用情況:
正如您所期望的那樣,主要的交互式會話,即會話1正在消耗最多的會話分頁池。
您可以將Testlimit工具與“-g 0”開關一起使用,以查看用于GDI對象的存儲空間耗盡時的情況。在-g是Testlimit分配的GDI位圖對象的大小后指定的數字,但大小為0的Testlimit只需嘗試并分配可能的最大對象。這是32位Windows XP系統的結果:
在沒有安裝終端服務的Windows XP或Windows Server 2003上,您可以使用Windows Driver Kit(WDK)中的Poolmon實用工具通過其池標記查看GDI對象分配。當Testlimit耗盡WIndows XP系統上的頁面緩沖池時,Poolmon的輸出看上去像這樣,當按字節分配(在Poolmon顯示中鍵入'b'按分配的字節排序),通過推論表明Gh05是位圖的標記Windows Server 2003上的對象:
在安裝了終端服務的Windows Server 2003系統上,在Windows Vista及更高版本上,必須使用Poolmon和/ s開關來指定要查看的會話。以下是在安裝了終端服務的Windows Server 2003系統上執行的Testlimit:
命令“poolmon / s1”顯示分配貢獻最大的標記。您可以在頂部看到Gh15標記,顯示不同的池標記正被用于位圖分配:
請注意,Testlimit如何在Windows XP系統上分配大約58 MB的位圖數據(該數字不占用位圖對象的GDI內部開銷),但Windows Server 2003系統上只有10 MB。較小的數字來自于Windows Server 2003終端服務器系統上的會話池只有32 MB,這大約是Poolmon顯示歸因于Gh15標記的內存量。“!vm 4”的輸出確認Session1的會話池已被占用,隨后嘗試從會話池分配GDI對象失敗:
您也可以使用!poolused內核調試器命令來查看會話池的使用情況。首先,使用帶/ p開關的.process命令和連接到會話的進程對象的地址切換到正確的會話。要查看特定會話中正在運行的進程,請使用!sprocess命令。下面是同一臺Windows Server 2003系統上的!poolmon的輸出,其中poolused的“c”選項用輸入的字節對輸出進行排序:
不幸的是,窗口管理器的堆標簽和它們代表的對象之間沒有公共映射,但是內核調試器的poolused命令使用調試器安裝目錄下的triage.ini文件來打印更多關于標簽的描述性信息。該命令報告Gh15是GDITAG_HMGR_SPRITE_TYPE,這只是稍微有點幫助,但其他更清楚。
幸運的是,大多數GDI和USER對象問題僅限于一個特定進程觸及每個進程10000個對象的限制,因此更高級的調查來確定哪個進程負責耗盡會話池或分配GDI對象以耗盡分頁池是不必要的。
下一次,我將看看系統頁面表項(系統PTE),這是另一個可能受到限制的關鍵系統資源,特別是在Windows Server 2003系統上的遠程桌面會話上。
總結
以上是生活随笔為你收集整理的推动Windows的限制:USER和GDI对象 - 第2部分的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 高级IO函数之fcntl m
- 下一篇: 2-5:C++快速入门之引用,引用和指针