推动Windows的限制:USER和GDI对象 - 第1部分
到目前為止,在“推動Windows系列的極限”中,我主要關(guān)注由Windows操作系統(tǒng)內(nèi)核管理的資源,包括物理和虛擬內(nèi)存,分頁和非分頁池,進程,線程和句柄。然而,在本文和下一篇文章中,我將探索Windows窗口管理器USER和GDI對象管理的兩個資源,這些資源表示窗口元素(如窗口和菜單)和圖形構(gòu)造(如鋼筆,畫筆和繪圖表面)。就像我在之前的文章中討論的其他資源一樣,耗盡各種USER和GDI資源限制可能導致不可預(yù)知的行為,包括應(yīng)用程序故障和不可用的系統(tǒng)。
與往常一樣,我建議您在此之前閱讀以前的帖子,因為與USER和GDI資源相關(guān)的一些限制是基于我所介紹的限制。這是我的另一個推動Windows的限制職位的完整索引:
推動Windows的限制:物理內(nèi)存
推動Windows的限制:虛擬內(nèi)存
推動Windows的限制:分頁和非分頁池
推動Windows的限制:進程和線程
推動Windows的限制:把手
會話,窗口站點和桌面
有一些概念使得USER對象,GDI對象和系統(tǒng)之間的關(guān)系更加清晰。首先是會議。會話表示交互式用戶登錄,它具有自己的鍵盤,鼠標和顯示器,并表示安全性和資源邊界。
會話概念是在Windows NT 4終端服務(wù)器版本中首次引入終端服務(wù)(現(xiàn)稱為遠程桌面服務(wù)),其中物理顯示,鍵盤和鼠標概念已為每個交互式遠程登錄系統(tǒng)的用戶虛擬化,終端核心服務(wù)功能已內(nèi)置到Windows 2000 Server中。在Windows XP中,利用會話來創(chuàng)建快速用戶切換(FUS)功能,使您可以在同一物理顯示屏,鍵盤和鼠標上的多個交互式登錄之間進行切換。
因此,會話可以與連接到系統(tǒng)的物理顯示器和輸入設(shè)備連接,與遠程桌面客戶端應(yīng)用程序呈現(xiàn)的邏輯顯示器和輸入設(shè)備連接,或者當您從遠程桌面客戶端應(yīng)用程序切換時處于斷開狀態(tài)與快速用戶切換的會話或終止遠程桌面客戶端連接而不注銷會話。
每個進程都與特定的會話相關(guān)聯(lián),您可以在將會話列添加到Sysinternals?Process Explorer時看到該會話。這個屏幕截圖中,我已經(jīng)折疊了進程樹,只顯示沒有父進程的進程,它來自于遠程桌面服務(wù)(RDS - 以前的終端服務(wù)器服務(wù))系統(tǒng),該系統(tǒng)有四個活動會話:會話0是專用會話,系統(tǒng)進程在Windows Vista及更高版本上執(zhí)行;?第一部分是我寫這篇文章的部分;?會話2是從另一個系統(tǒng)同時登錄的另一個用戶帳戶的會話;?最后,會話3是遠程桌面服務(wù)主動創(chuàng)建的,以便為下一個交互式登錄做好準備:
由于每個進程都與一個特定的會話相關(guān)聯(lián),操作系統(tǒng)通常只需要訪問當前進程會話的會話特定數(shù)據(jù),所以Windows在進程的虛擬地址空間中定義了一個進程會話數(shù)據(jù)視圖。因此,當系統(tǒng)在不同進程的線程之間切換時,也切換地址空間,切換當前會話視圖。例如,當Session 0的Csrss.exe進程是當前進程時,地址空間映射包括系統(tǒng)地址空間(包括在每個進程的地址空間中),Csrs的地址空間和Session 0地址空間。映射會話數(shù)據(jù)的內(nèi)存區(qū)域被稱為會話視圖空間或會話空間。當系統(tǒng)從會話1的資源管理器進程切換到線程時,映射會相應(yīng)地改變,
請注意,對于32位Windows Vista及更高版本,該數(shù)字并不完全正確,因為動態(tài)系統(tǒng)地址空間意味著會話空間不一定是連續(xù)的,并且可以根據(jù)需要在這些系統(tǒng)上進行增減。
下一個概念是桌面,一個由窗口管理器定義的對象,用于表示包含與桌面相關(guān)的窗口的虛擬顯示(注意,這不同于桌面的資源管理器定義,這是用戶使用快捷方式和其他對象的目錄用戶放置在那里)。默認的桌面被命名為“默認”,但是應(yīng)用程序可以創(chuàng)建額外的桌面并將連接切換到邏輯顯示,Sysinternals Desktops公用程序用來創(chuàng)建最多四個用戶可以切換的虛擬桌面。
最后,為了支持與同一窗口管理器實例相關(guān)聯(lián)的多個虛擬顯示器,窗口管理器定義窗口站對象。一個窗口站與一個特定的會話相關(guān)聯(lián),一個會話可以有多個窗口站,但是每個會話只有一個名為Winsta0的交互式窗口站,可以連接物理或邏輯顯示器,鍵盤和鼠標;?其他窗口站基本上是“無頭的”,對它們的支持僅僅是為了隔離期望窗口管理器服務(wù)的流程,但是不應(yīng)該這樣做。例如,系統(tǒng)為與帳戶中運行的進程關(guān)聯(lián)的每個服務(wù)帳戶創(chuàng)建非交互式窗口工作站,因為Windows服務(wù)不應(yīng)顯示用戶界面。
通過使用Sysinternals Winobj工具查看\ Windows目錄下的對象管理器命名空間(查看目錄需要以管理權(quán)限運行提升),可以看到與會話0相關(guān)的窗口工作站。在這里,您可以看到Microsoft Windows搜索服務(wù)創(chuàng)建的窗口工作站在三個內(nèi)置服務(wù)帳戶(系統(tǒng),網(wǎng)絡(luò)服務(wù)和本地服務(wù))以及會話0的交互式窗口工作站的每個窗口工作站中運行搜索過濾器:
您可以在對象管理器命名空間的Sessions目錄中看到與其他會話關(guān)聯(lián)的窗口工作站。這里是唯一的窗口站,與我的登錄會話相關(guān)的交互式WinSta0窗口站:
此圖顯示了一個系統(tǒng)的會話,窗口工作站和桌面之間的關(guān)系,該系統(tǒng)有一個用戶在物理控制臺上登錄到Session1,另一個用戶通過遠程桌面連接登錄到會話2,用戶運行虛擬桌面實用程序并切換顯示到Desktop1。
除了與特定會話相關(guān)聯(lián)外,進程還與特定的窗口工作站和桌面相關(guān)聯(lián),但進程可以在兩者之間進行切換,并且線程可以在桌面之間進行切換。因此,每個進程的關(guān)聯(lián)可以用一個分層的路徑來表示:“Session 1 \ WinSta0 \ Default”。在大多數(shù)情況下,您可以通過查看Process Explorer句柄視圖中的句柄表來間接確定哪個窗口工作站和桌面連接了一個進程,以查看已打開的對象的名稱。瀏覽器進程的句柄表的這個屏幕截圖顯示它連接到會話1的WinSta0上的默認桌面:
用戶對象
掌握基本概念之后,我們首先將注意力轉(zhuǎn)向USER對象。USER對象從它們表示桌面,窗口,菜單,游標,圖標和加速器表(菜單鍵盤快捷鍵)等用戶界面元素的名稱中獲取它們的名稱。盡管USER對象與特定的桌面相關(guān)聯(lián),但是它們必須可以從會話的所有桌面訪問,例如,允許在一個桌面上的進程注冊可以在任何桌面上輸入的熱鍵。出于這個原因,窗口管理器將作用范圍的USER對象標識符分配給窗口站。?
窗口管理器施加的基本限制是沒有進程可以創(chuàng)建超過10,000個USER對象。這種限制試圖防止單個進程耗盡與USER對象相關(guān)的資源,或者是因為它使用可能會創(chuàng)建過多數(shù)量的對象的算法進行編程,或者是因為它通過分配來泄漏對象,而不是在使用它們時刪除它們。通過使用-u開關(guān)運行Sysinternals?Testlimit實用程序,可以輕松驗證此限制,它指示Testlimit創(chuàng)建盡可能多的USER對象:
窗口管理器會跟蹤一個進程分配的USER對象的數(shù)量,當您將USER對象列添加到Process Explorer的顯示器時,您可以看到這些對象,這樣您就可以在分配的進程對象數(shù)量上保持選項卡。該屏幕截圖顯示,正如所料,Windows系統(tǒng)進程(包括Lsass.exe(本地安全機構(gòu)子系統(tǒng)))和服務(wù)進程(如Svchost)不會分配USER對象,因為它們沒有用戶界面:
Process Explorer顯示一個進程在進程屬性對話框的性能頁面上分配的USER對象的數(shù)量:
USER對象數(shù)量的一個基本限制來自于它們的標識符是在Windows的第一個版本(它們是16位)中的16位值。當在以后的版本中添加32位支持時,USER標識符必須保持限制為16位值,以便16位進程可以與由32位進程創(chuàng)建的窗口和其他USER對象交互。因此,65,535(2 ^ 16)是可以在會話上創(chuàng)建的USER對象總數(shù)的限制(由于歷史原因,窗口必須有偶數(shù)標識符,因此每個會話最多可以有32,768個窗口)。您可以通過使用-u開關(guān)運行Testlimit的多個副本來驗證此限制,直到無法再創(chuàng)建為止。假設(shè)您已經(jīng)運行的進程沒有使用過多的對象,
請確保您已準備好在您執(zhí)行此操作時將系統(tǒng)硬盤關(guān)閉,因為桌面可能無法使用。許多操作,比如甚至打開開始菜單的關(guān)閉菜單,都需要USER對象,當沒有更多的操作可以被分配時,系統(tǒng)會以奇怪的方式運行。我甚至無法通過在USER對象耗盡之后單擊其關(guān)閉菜單按鈕來終止我運行的記事本程序。
到目前為止,我只談到與進程或窗口工作站可以分配的絕對數(shù)量的USER對象相關(guān)的限制,但是還有其他用于USER對象本身的存儲器的限制。每個桌面都有自己的內(nèi)存區(qū)域,稱為桌面堆,從桌面堆上分配大多數(shù)USER對象。因為桌面堆被存儲在會話空間中,并且32位地址空間限制了內(nèi)核模式地址空間的數(shù)量,所以桌面堆的大小被限制在相對適中的量。它們的大小也有所不同,具體取決于所使用的桌面類型以及系統(tǒng)是32位還是64位系統(tǒng)。
Matthew Justice的桌面堆概述和桌面堆,第2部分?? 來自NT調(diào)試博客的文章在通過Windows Vista SP1記錄桌面堆大小方面做得非常出色。此表總結(jié)了Windows Server 2008 R2之間的Windows版本的大小:
| ? | 交互式桌面 | 非交互式桌面 | Winlogon桌面 | 斷開桌面 |
| Windows XP 32位 | 3 MB | 512 KB | 128 KB | 64 KB |
| Windows Server 2003 32位 | 3 MB | 512 KB | 128 KB | 64 KB |
| Windows Server 2003 64位 | 20 MB | 768 KB | 192 KB | 96 KB |
| Windows Vista / Windows Server 2008 32位 | 12 MB | 512 KB | 128 KB | 64 KB |
| Windows Vista / Windows Server 2008 64位 | 20 MB | 768 KB | 192 KB | 96 KB |
| Windows 7 32位 | 12 MB | 512 KB | 128 KB | 64 KB |
| Windows 7 / Windows Server 2008 R2 64位 | 20 MB | 768 KB | 192 KB | 96 KB |
值得注意的是,Windows Vista 32位版本的原始版本具有以前的32位版本的Windows所具有的3 MB交互式堆大小。發(fā)布之后,我們的遙測顯示有些用戶偶爾會用完堆,大概是因為他們在內(nèi)存更多的系統(tǒng)上運行的應(yīng)用程序更多,所以SP1將大小提高到12 MB。也可以使用Matthew的文章中描述的注冊表設(shè)置來覆蓋默認的桌面堆大小。
在Windows Vista之前的Windows版本中,可以使用Microsoft?桌面堆監(jiān)視器工具來查看桌面堆的大小以及每個堆大小的使用情況。以下是在32位Windows XP系統(tǒng)上的工具輸出,顯示在交互式桌面上只有5.6%的堆(172 KB)已被使用:
該工具尚未針對Windows Vista進行更新,因為較新版本W(wǎng)indows上的較大桌面堆大小意味著在其他USER對象限制命中之前,桌面堆很少用盡。但是,您可以使用Testlimit和-u和-i開關(guān)來查看交互式桌面堆耗盡情況下系統(tǒng)的行為。交換機組合具有Testlimit創(chuàng)建窗口類的數(shù)據(jù)結(jié)構(gòu),具有4 KB額外的類存儲,直到失敗。以下是在捕獲上述桌面堆監(jiān)視器輸出后立即運行時的Testlimit輸出。2823 KB加上桌面堆監(jiān)視器已經(jīng)分配的172 KB等于約3 MB:
雖然沒有辦法確定在新系統(tǒng)上有多少堆正在使用,但當堆耗盡時,窗口管理器會將事件寫入系統(tǒng)事件日志,以幫助解決窗口管理器問題:
這涵蓋了USER對象限制。請繼續(xù)關(guān)注第2部分,我將討論與窗口管理器GDI對象有關(guān)的限制。
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的推动Windows的限制:USER和GDI对象 - 第1部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何用ASPxGridView绑定多表关
- 下一篇: (计算机组成原理)第三章存储系统-第五节