我們?cè)谏钊胍稽c(diǎn)。在下圖中展示了session0的基本組成,其中有個(gè)名為Bob的用戶(hù)登入。正如你所看到的,Winsta0包含用戶(hù)控制臺(tái)中的所有進(jìn)程還有任何被標(biāo)記為可交互(Interactive)的任何服務(wù)。本例中,Winsta0包括winlogon.exe,explorer.exe和其他需要與用戶(hù)交互的服務(wù)。名為service-0x0-3e7$的Windows station 擁有在Local system帳號(hào)下且不與用戶(hù)交互的所有服務(wù)。本例中service.exe正是這樣的服務(wù)。,正如你所看到的連接線(xiàn),將來(lái)自各個(gè)不同虛擬session的進(jìn)程載入到單個(gè)windows station。SQL進(jìn)程被載入到其自身的windows station并且使用自己的證書(shū)認(rèn)證,所以它不屬于其他兩個(gè)windows station。

因此,我們可以將上圖總結(jié)如下:
- 整個(gè)圖展示的是session0.
- 在Bob帳號(hào)下的所有進(jìn)程都載入到Winsta0。
- 在local system帳號(hào)下可交互進(jìn)程載入到winsta0。
- 在local system帳號(hào)下不可交互進(jìn)程載入到Service-0x0-3e7% windows station 。
- 在私有證書(shū)下啟動(dòng)的進(jìn)程載入到其自己的windows station(像SQL)。
一個(gè)單獨(dú)的桌面堆分配給一個(gè)單獨(dú)的桌面對(duì)象。這個(gè)堆包含各種人機(jī)交互對(duì)象,包括窗口,目錄和鉤子。當(dāng)應(yīng)用程序需要引用一個(gè)人機(jī)交互對(duì)象時(shí),它將會(huì)去調(diào)用user32.dll去分配該對(duì)象,并且分配的每一個(gè)交互對(duì)象都會(huì)占用一部分桌面堆。如果桌面堆趨于耗盡,你將會(huì)看到不正常顯示或其他不正常現(xiàn)象。并且,如果session視圖存儲(chǔ)區(qū)耗盡,session將不能在創(chuàng)建更多的桌面堆。當(dāng)然兩者中的任何一個(gè)出現(xiàn)都是不好的。這就是或許為什么當(dāng)你還有很多內(nèi)存剩余的時(shí)候仍然會(huì)接到“內(nèi)存耗盡錯(cuò)誤”的原因。
當(dāng)這種情況發(fā)生時(shí),你可能會(huì)收到“初始化錯(cuò)誤”伴隨著視窗不正常顯示。一個(gè)典型的錯(cuò)誤是 0xc0000142,意思是 STATUS_DLL_INIT_FAILED。你可以從癥狀中得知引發(fā)問(wèn)題的原因是由于單個(gè)桌面堆還是整個(gè)會(huì)話(huà)引起的。如果桌面堆耗盡,你僅僅會(huì)看到與該窗口堆相關(guān)的進(jìn)程出現(xiàn)問(wèn)題。如果是session視圖存儲(chǔ)區(qū)耗盡,你會(huì)看到整個(gè)session出現(xiàn)問(wèn)題。
win32k.sys有一個(gè)固定的48M的存儲(chǔ)空間分配給桌面堆。在終端服務(wù)中,這個(gè)空間是被每個(gè)session所共享,結(jié)果是僅僅留出20MB給桌面堆。所以,在終端服務(wù)器上比在個(gè)人電腦上更容易出現(xiàn)桌面堆耗盡的情況。但在vista和windows server2008中由于桌面堆是動(dòng)態(tài)分配的,所以48M的限制不復(fù)存在。
注冊(cè)表項(xiàng) HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems 用來(lái)設(shè)定這個(gè)存儲(chǔ)區(qū)的大小,它的值形如“%SystemRoot%system32csrss.exe ObjectDirectory=Windows SharedSection=1024,3072,512 Windows … ”
需要關(guān)注的是"SharedSection=1024,3072,512". 這三個(gè)值決定了將有多少KB的空間分配給桌面堆的各個(gè)部分。第一個(gè)值指示所有桌面共享堆的大小,用來(lái)存儲(chǔ)全局句柄表和共享系統(tǒng)設(shè)置。默認(rèn)值是1024KB,一般情況下不需要修改這個(gè)值。第二個(gè)值指示分配個(gè)每個(gè)在可交互windows station中桌面堆的大小,用來(lái)存儲(chǔ)諸如鉤子,菜單,字符串和窗口之類(lèi)的對(duì)象,默認(rèn)值是3072KB。登錄的用戶(hù)越多,創(chuàng)建的桌面就越多。結(jié)果是,所有桌面堆大小的總和增加以反映創(chuàng)建的桌面數(shù)增加。然而,每個(gè)桌面僅僅擁有3072KB的可交互桌面堆大小。第三個(gè)值指示分配個(gè)每個(gè)在不可交互windows station中桌面堆的大小,默認(rèn)值是512KB,如果沒(méi)有設(shè)定,將于第二個(gè)值相同。
在用戶(hù)帳號(hào)下的每個(gè)服務(wù)進(jìn)程都會(huì)由SCM(Service Control Manager )在不可交互window station下分配一個(gè)桌面。因此,每個(gè)這樣的服務(wù)都會(huì)消耗一部分向SharedSection中第三個(gè)值設(shè)定的桌面堆的大小。在可交互和不可交互wndow station下的桌面堆的總大小必須在48M以?xún)?nèi)。所以,減小在sheareSection中第二或第三個(gè)值的大小會(huì)增加可以被創(chuàng)建的總桌面數(shù)的大小,相應(yīng)的也會(huì)減少在各自桌面內(nèi)科創(chuàng)建的鉤子,菜單,字符串和窗口的數(shù)量。反之亦然。同樣,增加SharedSection第三個(gè)值的大小會(huì)減少用戶(hù)帳號(hào)下可運(yùn)行的服務(wù)數(shù)量
參考文章: