Share via


Desktop Heap Overview

"이 문서는 https://blogs.msdn.com/ntdebugging blog 의 번역이며 원래의 자료가 통보 없이 변경될 수 있습니다. 이 자료는 법률적 보증이 없으며 의견을 주시기 위해 원래의 blog 를 방문하실 수 있습니다. (https://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx)"
아래 번역은 저와 함께 작업하는 한주성 씨가 해 주셨습니다. 감사합니다.

Desktop Heap Overview

Desktop Heap이 무엇인지 알기 위해 많은 시간을 소비하지 않아도 될 것입니다. Desktop Heap 고갈은 가끔 문제의 원인이 될 것이고 이 글을 도움이 될 것 입니다.

비스타에서는 커널 주소 공간이 대폭 변경되었지만, 여기에서는 비스타에 대한 내용은 포함하지 않았습니다.

기초 다지기 : Session Space

Desktop Heap을 이해하기 위해서는 먼저 Session Space를 이해하여야 합니다.

Windows 2000, Xp, 2003에서는 제한이 있기는 하지만 Kernel mode의 Session Space는 설정이 가능합니다. 하나의 Session은 하나의 유저 로그온 환경으로, 많은 processes가 여기에 속하게 됩니다

터미널 서비스가 없는 Windows 2000은 오르지 하나의 세션만 존재하며 Session Space는 존재하지 않습니다. 하지만 Windows XP, 2003에는 항상 Session Space가 존재합니다. Session space range 는 virtual address range 입니다. 앞의 주소 범위를 통해 현재 세션에 Page를 할당할수 있는 map를 만듭니다. 이런 방식의, 같은 Session의 모든 processes는 같은 Page Session에 Map 되고, 다른 session의 모든 processes는 다른 Page Session에 Map됩니다.

Session space안에는. session image space , session structure , session view space , session paged pool로 4개로 분리된 영역으로 구분 됩니다.

session image space 는 복사된 Session 고유의 수정되지 않는 Win32k.sys data, 복사된 전역 win32k.sys code와 수정되지 않은 data, 다양한 Session driver 같은 video driver, TS remote protocol driver, 등을 로드하고,session structure는 세션을 위해 여러 session working set list (WSL) 정보를 포함하여 memory management (MM) control 구조체로 보유합니다..

Session paged pool은 specific Paged Pool을 할당하여 줍니다.

Windows XP는 Session방식이 아닌 일반적인 Page Pool을 사용합니다. 때문에 원격 데스크톱 연결 수에 제한이 있습니다. 하지만 Windows 2003 구조는 정해진 Page pool 대신에 Session page pool로 할당한다.

만약 Terminal Service(Application Mode)를 인스톨 하였다면,

Session view space는 Session을 위한 desktop heap을 포함하여 session mapped views을 가지게 됩니다.

Session Space layout:

 

Session Image Space: win32k.sys, session drivers
Session Structure: MM structures and session WSL
Session View Space: session mapped views, including desktop heap
Session Paged Pool

 

Sessions, Window Stations, 그리고 Desktops

이미 Desktop heap이 Desktops과 함께 무언가 한다는 것을 짐작 했을 것 입니다

어떻게 desktops과 Sessions 과 Window stations이 어떻게 desktops과 관계되는지 몇 분간 생각해 봅시다

모든 Win32 processes는 실행되기 위해 Desktop object에 속해야 합니다.

Desktop은 논리적으로 보이는 외형과 Windows, Menus, Hooks을 포함합니다

그리고 모든 Desktop은 Windows station에 포함됩니다

Windows station은 object를 포함하는데 그것들은 clipboard, 전역으로 지정된 atom, desktop object 그룹입니다. 각각 Session에서, 단 하나의 Windows station이 사용자가 동작하도록 허가합니다. 바로 Windows station의 이름은 “Winsta0”입니다

모든 Windows station은 Session에 포함됩니다.

Session 0는 서비스의 실행과 콘솔(최고권한)이라는 것을 나타냅니다(Pre Vista). 이외 Session들은 (session1, session2, 등등등) 일반적으로 remote desktops / terminal server sessions 혹은 빠른 사용자 전환(Fast User Switching)기능을 통해 콘솔에 붙어있는 Session입니다.

그래서 정리하면 Session은 하나 혹은 하나이상의 Windows station을 포함하고, Windows station은 하나 혹은 하나이상의 Desktops를 포함합니다.

이제 아래 그림의 관계를 이해할 수 있을 것 입니다. 이 샘플은 전형적인 시스템의 Desktop 구조입니다.

- Session 0

| |

| ---- WinSta0 (interactive window station)

| | |

| | ---- Default (desktop)

| | |

| | ---- Disconnect (desktop)

| | |

| | ---- Winlogon (desktop)

| |

| ---- Service-0x0-3e7$ (non-interactive window station)

| | |

| | ---- Default (desktop)

| |

| ---- Service-0x0-3e4$ (non-interactive window station)

| | |

| | ---- Default (desktop)

| |

| ---- SAWinSta (non-interactive window station)

| | |

| | ---- SADesktop (desktop)

| |

- Session 1

| |

| ---- WinSta0 (interactive window station)

| | |

| | ---- Default (desktop)

| | |

| | ---- Disconnect (desktop)

| | |

| | ---- Winlogon (desktop)

| |

- Session 2

|

---- WinSta0 (interactive window station)

|

---- Default (desktop)

|

---- Disconnect (desktop)

|

---- Winlogon (desktop)

 

위 그림에서 SADesktop의 전체 경로는 “Session 0\SAWinSta\SADesktop”가 됩니다.

 

Desktop Heap – 이게 무엇일까?, 무엇을 위해 이것을 사용하나?

모든 Desktop object는 하나의 desktop heap과 함께 조합됩니다. Desktop heap은 windows, menus, hooks와 함께 user interface objects를 저장합니다. application이 user interface object를 필요로 할 때, function들 안에 user32.dll을 불려 들어 저 object들을 할당합니다. 만약 application이 user32.dll을 의존하지 않는다면, desktop heap을 소비하지 않을 것 입니다. 다음 샘플은 언제 application이 desktop heap을 사용하는지 나타냅니다.

1. application이 윈도우 창을 만들고자 할 때, user32.dll의 CreateWindowsEx를 불려 들일 때

2. win32k.sys에서 user32.dll로 kernel mode의 system call을 만들 때

3. win32k.sys로 desktop heap에서 window object를 할당 할 때

4. window (an HWND)가 호출자 에게 돌아가는 것을 처리 할 때

5. application과 그 밖에 다른 processes는 같은 Session 에서 HWND 값에 의해 window object를 참조할 때

어딘가 잘못될 때

이것은 단지 “공부” 입니다. 그리고 유저 혹은 응응 프로그램 개발자에게 필요한 Desktop heap 사용에 대한 주의사항도 그 어느 쪽도 아닙니다. 단지 다음 2가지 기본적인 시나리오를 통해 desktop heap의 장애를 발생 시킬 수 있다는 것만 알아두시기 바랍니다.

첫 번째 시나리오는 Session view space를 주어진 Session을 위해 전부 이용하였을 때, 새로운 desktop heap을 만들지 못하게 됩니다.

두 번째 시나리오는 사용중인 desktop heap을 전부 할당하였을 때, desktop heap의 threads가 사용한 desktop에서 추가적인 desktop heap이 사용이 불가능하게 됩니다.

그럼 당신은 어떻게 위 문제점이 발생하였는지 알수 있을까요? User32.dll의 processes가 에러메세지“STATUS_DLL_INIT_FAILED (0xC0000142)”와 함께 발생한 장애라고 알립니다. 이것은 일반적인 증상입니다.. user32.dll은 desktop heap의 function을 필요하기 때문에, user32.dll의 초기화 진행 실패는 desktop heap을 고갈시키게 됩니다. 또 다른 문제점인 새로운 Windows 생성에 실패를 당신을 아마 보았을 것 입니다. application에 따라서, 이 같은 실패는 다른 방법을 취급할지도 모릅니다. 요약하면 만약 앞의 문제점중 하나를 경험 하셨다면, 이런 문제점의 보통 하나의 Session에서 존재합니다. 만약 위 2개의 문제점을 보았다면, 증상인 processes 은 desktop heap의 고갈 일것입니다.

문제점 진단

그럼 Desktop heap 고갈 문제를 당신은 어떻게 할건가요? 이것은 여러 가지로 접근할 수 있습니다. 그 중 한가지를 진행하겠습니다. Dheapmon은 커맨드 툴로써 desktop heap이 사용하는 Session안의 모든 desktop들을 출력하여 줍니다. 해당툴 다운로드 경로는 우리 블로그 첫번째 글에서 확인하실수 있습니다. 해당 포스트를 확인후 설치 합니다. session에서 Desktop heap이 문제가 있다 생각 될 때 실행하시기 바랍니다. 만약 실행이 실패하였다면, session 0(관리자 모드)에서실행하지 않았거나(dheapmon은 관리자 모드를 요구합니다.), Terminal server session일것입니다.

Desktop Heap Information Monitor Tool (Version 7.0.2727.0)

Copyright (c) 2003-2004 Microsoft Corp.

-------------------------------------------------------------

Session ID: 0 Total Desktop: ( 5824 KB - 8 desktops)

WinStation\Desktop Heap Size(KB) Used Rate(%)

-------------------------------------------------------------

WinSta0\Default 3072 5.7

WinSta0\Disconnect 64 4.0

WinSta0\Winlogon 128 8.7

Service-0x0-3e7$\Default 512 15.1

Service-0x0-3e4$\Default 512 5.1

Service-0x0-3e5$\Default 512 1.1

SAWinSta\SADesktop 512 0.4

__X78B95_89_IW\__A8D9S1_42_ID 512 0.4

실행하면 아마도 당신은 위 예제 그림을 보게 될 것입니다. 각각의 desktop heap의 크기를 알 수 있고, 퍼센트로도 확인이 가능합니다. 만약 desktop heap 어느 하나가 꽉 차게 된다면, desktop 할당은 실패하게 됩니다. 만약 모든 desktop에 누적되는 desktop heap 크기가 session view space의 전체 크기에 접근하게 될 경우, 그 session안에서 새로운 desktop은 만들 수 없습니다. 앞에서 이야기한 2개의 실패의 시나리오는 session view space의 전체 크기, 그리고 각각의 desktop heap의 할당 크기가 원인이며, 이들의 크기는 설정이 가능합니다.

session view space의 크기 설정하기

Session View Size라는 레지스트리 값의 수정을 통해 session view space의 크기를 변경할 수 있습니다.

이것은 REG_DWORD이며 입력 값은 megabytes로 설정이 됩니다.

메모 : 아래 나열된 리스트의 값은 32bit x86시스템에서 /3GB 옵션을 사용하지 않은 것입니다.

주의. 값을 수정한 후에는 재 부팅을 하여야 값이 적용됩니다. 그 각각의 값은 아래와 같습니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

OS Size if no registry value configured Default registry value
Windows 2000 * 20 MB none
Windows XP 20 MB 48 MB
Windows Server 2003 20 MB 48 MB

 

* Windows 2000에서는 터미널 서비스를 설치하고 hotfix 318942를 설치 하여야 합니다. 터미널 서비스를 설치하지 않으면, desktop heap은 존재 하지 않습니다. desktop heap 할당은 systeam mapped views를 위해 48MB로 조정된 영역에서 만들어 집니다. Hotfix 318942를 설치하면, session view space는 20MB로 설정됩니다..

32bit 운영체제에서는 Session view space와 Session paged pool의 크기의 합은 최대 500MB입니다(이론상), 최대값은 램과 몇 개의 레지스트리 값에 의해 변화합니다. 실제로는 최대값은 대부분 450MB정도 됩니다. 위의 값이 증가할 경우, 그것은 다음, 그것이 어떤 조합이든지 nonpaged pool, system PTEs, System cache, paged pool은 가상 주소 공간 감소되는 결과를 가져올게 될것입니다.

개별 desktop heap 사이즈 조정

개별 desktop heap 사이즈 구성은 조금 복잡하게 되어 있습니다. Desktop heap 크기의 3가지 조건에 대해 애기하겠습니다.

  • Desktop은 interactive Windows station 그리고, “Disconnect” 또는 “Winlogon” desktop 면, 이 heap의 크기는 각각 64Kb 또근 128kb로 고정됩니다.(32bit x86)
  • Desktop은 interactive Windows station 이고, 위의 desktops이 아니면, 이 desktop heap의 크기는 조정이 가능합니다.
  • Desktop은 uninteractive Windows station이면, 이 Desktop heap 크기 역시 조정 가능합니다.

Desktop heap 크기를 조정하는 레지스트리 값 위치는 다음과 같습니다.
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows

위 위치의 기본 값은 다음과 같습니다. (한줄입니다.)
%SystemRoot%\system32\csrss.exe ObjectDirectory=\WindowsSharedSection=1024,3072,512 Windows=On SubSystemType=WindowsServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=OffMaxRequestThreads=16

계산하는 값은 “SharedSection=”으로 어떻게 desktop heap을 할당한지 조정합니다. 단위는 Kilobyte입니다.

최초 SharedSection의 값 1024는 일반적인 모든 desktop들의 heap 사이즈 입니다. 이 메모리는 desktop heap 할당이 아닙니다. 그리고 이 desktop heap 주소 문제로 이 값은 변경되면 안됩니다.

두 번째 SharedSection의 값 3072는 상호 작용하는 Windows station과 함께 조합되는 각각의 desktop을 할당하기 위한 크기 입니다. “Disconnect”와 “Winlogin” desktop은 제외

세 번째 SharedSection의 값 512는 "non-interactive" Windows station과 함께 조합되는 각각의 desktop을 할당하기 위한 크기입니다.

2개의 Desktop heap이 고갈되는 시나리오를 위의 기술된 내용에 주의 하시기 바랍니다.

만약 첫번째 시나리오는 만났다면(Session view space가 고갈되는 현상), 그리고 상호 작용하지 않는 더 많은 Desk top heap들, 그때 세번째 SharedSection이 더 작은 Non-Interactive Desktop heap의 생성하도록 좀더 허용해 줄수 있습니다.. 물론 이것은 아마 Non-Interactive heaps의 제한량인 512KB가 가득 차서, 선택권이 없을 지도 모릅니다. 또 두 번째 시나리오는 만났다면(Single Desktop heap을 전부 할당했음),그때 두번째 또는 세번째 SharedSection는 각 Desktop heap을 3072나 512KB보다 더 큰값을 허용하도록 증가시킬수 있습니다. 발생가능한 문제점은 몇몇 전체 Desktop heap을 제작할 수 있습니다.

왜 모든 Window stations과 Desktop은 Session 0에 있는가?

방금 우리는 Sess view Space 와 Desktops의 사이즈를 고치는 방법을 알았습니다. 이것으로 당신은 다음과 같은 질문을 하실 수 있습니다. 당신은 왜 많은 Windows station과 desktop들을 그중에서토 Session 0에 있는지… 먼저, 당신을 WinSta0 에서 적은 3개의 desktop을 발견할수 있습니다. 그리고 각각 3개의 desktop은 다양한 esktop heap의 합을 사용합니다.

저는 앞에서 간단히 애기를 해드린적이 있지만, 다시 말씀드리겠습니다. 각각 interactive Window station인 그 3개의 desktop 대해

  • Default desktop - 아래 설명한대로 설정가능한 desktop heap 크기입니다.
  • Disconnect desktop - 32-bit systems에서 desktop heap 크기가 64k입니다.
  • Winlogon desktop - 32-bit systems에서 desktop heap 크기가 128k입니다.

노트 : 어떤 Process든지 CreateDesktop을 사용하고 새로운 Desktop을 창조할 수 있기 때문에 Winsta0의 더 많은 desktops에서 마찬가지로 사용이 가능합니다.

non-interactive window stations과 관련된 Desktop으로 이동해 봅시다 : 이들은 보통 서비스와 관련이 있습니다. 시스템이 하나의 Window station을 만들 때 하나의 서비스 processes가 그 아래에서 로컬 시스템 계정으로 실행되게 됩니다. 그 Windows station의 이름은 service-0x0-3e7$. 이 이름은 로컬 시스템 계정을 위한 LUID입니다. 그리고 하나의 desktop은 저 이름이 지정된 기본값입니다. 어째든 서비스 processes들은 저것들이 실행될 때 Local System처럼 Winsta0과 상호작용이 시작됩니다 그래서 Session0의 유저와 작용 할 수 있습니다.

이미 존재하는 Windows station의 LUID을 제외하고, 모든 서비스 processes들은 시작시 그 아래에서 특정 유자 나 서비스 계정을 사용하여 Service Control Manager에 의해 Windows station과 Desktop이 생성됩니다.

이 Windows station은 상호작용하지 않는 window station들 입니다. Window station의 이름은 기본적으로 LUID가 됩니다. 이는 모든 로그온을 위해 유일합니다. 다수시간을 실제 기록할 경우, 새로운 Windows station이 각각 로그인 하여 생성됩니다. 예로 windows station의 이름이 “service-0x0-22e1$”인 것이 있습니다.

일반적으로 desktop heap의 문제점들은 시스템에서 매우 큰 번호의 서비스가 존재할 때 발생합니다. 이 큰 번호의 유일한 서비스 또는 하나의 다수의 시간 동안 설치되는 서비스(불완전하게 설계됨, IMHO) 일수 있습니다. 모든 서비스가 로컬시스템 계정 밑에서 실행되는 경우에, Session 0\Service-0x0-3e7$\Default를 위한 Desktop heap은 모두 소진해 버릴지도 모릅니다.

서비스가 전부 매번 새로운 LUID를 취득하여 여러 시간을 다른 사용자 계정의 밑에서 실행되는 경우는, 각각의 단계의 서비스를 위해 생성된 새로운 desktop heap과 Session view space는 최후에 소진될 것입니다.

당신은 서비스 processes들이 어떻게 windows station들과 Desktop들을 사용하는지 알게 되었습니다. 당신이 Desktop heap 문제점을 해결하기 위해 이 지식을 이용할 것 입니다. 예를 들면 당신은 Session 0\Service-0x0-3e7$\Default을 위한 desktop heap을 다 사용한 경우 당신은 어떤 새로운 서비스의 밑에서 실행되는 사용자 계정을 바꾸어 새로운 Windows station 과desktop으로 이동 시킬수도 있습니다.