Desktop Heap Overview

Desktop Heap Overview

Rate This

 

Desktop heap is probably not something that you spend a lot of time thinking about, which is a good thing.  However, from time to time you may run into an issue that is caused by desktop heap exhaustion, and then it helps to know about this resource.  Let me state up front that things have changed significantly in Vista around kernel address space, and much of what I’m talking about today does not apply to Vista.

 

Laying the groundwork: Session Space

To understand desktop heap, you first need to understand session space.  Windows 2000, Windows XP, and Windows Server 2003 have a limited, but configurable, area of memory in kernel mode known as session space.  A session represents a single user’s logon environment.  Every process belongs to a session.  On a Windows 2000 machine without Terminal Services installed, there is only a single session, and session space does not exist.  On Windows XP and Windows Server 2003, session space always exists.  The range of addresses known as session space is a virtual address range.  This address range is mapped to the pages assigned to the current session.  In this manner, all processes within a given session map session space to the same pages, but processes in another session map session space to a different set of pages. 

Session space is divided into four areas: session image space, session structure, session view space, and session paged pool.  Session image space loads a session-private copy of Win32k.sys modified data, a single global copy of win32k.sys code and unmodified data, and maps various other session drivers like video drivers, TS remote protocol driver, etc.  The session structure holds various memory management (MM) control structures including the session working set list (WSL) information for the session.  Session paged pool allows session specific paged pool allocations.  Windows XP uses regular paged pool, since the number of remote desktop connections is limited.  On the other hand, Windows Server 2003 makes allocations from session paged pool instead of regular paged pool if Terminal Services (application server mode) is installed.  Session view space contains mapped views for the session, including desktop heap. 

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, and Desktops

You’ve probably already guessed that desktop heap has something to do with desktops.  Let’s take a minute to discuss desktops and how they relate to sessions and window stations.  All Win32 processes require a desktop object under which to run.  A desktop has a logical display surface and contains windows, menus, and hooks.  Every desktop belongs to a window station.  A window station is an object that contains a clipboard, a set of global atoms and a group of desktop objects.  Only one window station per session is permitted to interact with the user. This window station is named "Winsta0."  Every window station belongs to a session.  Session 0 is the session where services run and typically represents the console (pre-Vista).  Any other sessions (Session 1, Session 2, etc) are typically remote desktops / terminal server sessions, or sessions attached to the console via Fast User Switching.  So to summarize, sessions contain one or more window stations, and window stations contain one or more desktops.

You can picture the relationship described above as a tree.  Below is an example of this desktop tree on a typical system:

- 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)

 

In the above tree, the full path to the SADesktop (as an example) can be represented as “Session 0\SAWinSta\SADesktop”.

 

Desktop Heap – what is it, what is it used for?

Every desktop object has a single desktop heap associated with it.  The desktop heap stores certain user interface objects, such as windows, menus, and hooks.  When an application requires a user interface object, functions within user32.dll are called to allocate those objects.  If an application does not depend on user32.dll, it does not consume desktop heap.  Let’s walk through a simple example of how an application can use desktop heap. 

1.     An application needs to create a window, so it calls CreateWindowEx in user32.dll.

2.     User32.dll makes a system call into kernel mode and ends up in win32k.sys.

3.     Win32k.sys allocates the window object from desktop heap

4.     A handle to the window (an HWND) is returned to caller

5.     The application and other processes in the same session can refer to the window object by its HWND value

 

Where things go wrong

Normally this “just works”, and neither the user nor the application developer need to worry about desktop heap usage.  However, there are two primary scenarios in which failures related to desktop heap can occur:

  1. Session view space for a given session can become fully utilized, so it is impossible for a new desktop heap to be created.
  2. An existing desktop heap allocation can become fully utilized, so it is impossible for threads that use that desktop to use more desktop heap.

 

So how do you know if you are running into these problems?  Processes failing to start with a STATUS_DLL_INIT_FAILED (0xC0000142) error in user32.dll is a common symptom.  Since user32.dll needs desktop heap to function, failure to initialize user32.dll upon process startup can be an indication of desktop heap exhaustion.  Another symptom you may observe is a failure to create new windows.  Depending on the application, any such failure may be handled in different ways.  Note that if you are experiencing problem number one above, the symptoms would usually only exist in one session.  If you are seeing problem two, then the symptoms would be limited to processes that use the particular desktop heap that is exhausted.

 

Diagnosing the problem

So how can you know for sure that desktop heap exhaustion is your problem?  This can be approached in a variety of ways, but I’m going to discuss the simplest method for now.  Dheapmon is a command line tool that will dump out the desktop heap usage for all the desktops in a given session.  See our first blog post for a list of tool download locations.  Once you have dheapmon installed, be sure to run it from the session where you think you are running out of desktop heap.  For instance, if you have problems with services failing to start, then you’ll need to run dheapmon from session 0, not a terminal server session.

Dheapmon output looks something like this:

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

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

 

As you can see in the example above, each desktop heap size is specified, as is the percentage of usage.  If any one of the desktop heaps becomes too full, allocations within that desktop will fail.  If the cumulative heap size of all the desktops approaches the total size of session view space, then new desktops cannot be created within that session.  Both of the failure scenarios described above depend on two factors: the total size of session view space, and the size of each desktop heap allocation.  Both of these sizes are configurable. 

 

Configuring the size of Session View Space

Session view space size is configurable using the SessionViewSize registry value.  This is a REG_DWORD and the size is specified in megabytes.  Note that the values listed below are specific to 32-bit x86 systems not booted with /3GB.  A reboot is required for this change to take effect.  The value should be specified under:

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

* Settings for Windows 2000 are with Terminal Services enabled and hotfix 318942 installed.  Without the Terminal Services installed, session space does not exist, and desktop heap allocations are made from a fixed 48 MB region for system mapped views.  Without hotfix 318942 installed, the size of session view space is fixed at 20 MB.

The sum of the sizes of session view space and session paged pool has a theoretical maximum of slightly under 500 MB for 32-bit operating systems.  The maximum varies based on RAM and various other registry values.  In practice the maximum value is around 450 MB for most configurations.  When the above values are increased, it will result in the virtual address space reduction of any combination of nonpaged pool, system PTEs, system cache, or paged pool.

 

Configuring the size of individual desktop heaps

Configuring the size of the individual desktop heaps is bit more complex.  Speaking in terms of desktop heap size, there are three possibilities:

·         The desktop belongs to an interactive window station and is a “Disconnect” or “Winlogon” desktop, so its heap size is fixed at 64KB or 128 KB, respectively (for 32-bit x86)

·         The desktop heap belongs to an interactive window station, and is not one of the above desktops.  This desktop’s heap size is configurable.

·         The desktop heap belongs to a non-interactive window station.  This desktop’s heap size is also configurable.

 

The size of each desktop heap allocation is controlled by the following registry value:

            HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows

 

 The default data for this registry value will look something like the following (all on one line):

               %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows

               SharedSection=1024,3072,512 Windows=On SubSystemType=Windows

               ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3

               ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off

               MaxRequestThreads=16

                                                           

 

The numeric values following "SharedSection=" control how desktop heap is allocated. These SharedSection values are specified in kilobytes.

The first SharedSection value (1024) is the shared heap size common to all desktops. This memory is not a desktop heap allocation, and the value should not be modified to address desktop heap problems.

The second SharedSection value (3072) is the size of the desktop heap for each desktop that is associated with an interactive window station, with the exception of the “Disconnect” and “Winlogon” desktops.

The third SharedSection value (512) is the size of the desktop heap for each desktop that is associated with a "non-interactive" window station. If this value is not present, the size of the desktop heap for non-interactive window stations will be same as the size specified for interactive window stations (the second SharedSection value). 

Consider the two desktop heap exhaustion scenarios described above.  If the first scenario is encountered (session view space is exhausted), and most of the desktop heaps are non-interactive, then the third SharedSection can be decreased in an effort to allow more (smaller) non-interactive desktop heaps to be created.  Of course, this may not be an option if the processes using the non-interactive heaps require a full 512 KB.  If the second scenario is encountered (a single desktop heap allocation is full), then the second or third SharedSection value can be increased to allow each desktop heap to be larger than 3072 or 512 KB.  A potential problem with this is that fewer total desktop heaps can be created.

 

What are all these window stations and desktops in Session 0 anyway?

Now that we know how to tweak the sizes of session view space and the various desktops, it is worth talking about why you have so many window stations and desktops, particularly in session 0.  First off, you’ll find that every WinSta0 (interactive window station) has at least 3 desktops, and each of these desktops uses various amounts of desktop heap.  I’ve alluded to this previously, but to recap, the three desktops for each interactive window stations are:

·         Default desktop - desktop heap size is configurable as described below

·         Disconnect desktop - desktop heap size is 64k on 32-bit systems

·         Winlogon desktop - desktop heap size is 128k on 32-bit systems

 

Note that there can potentially be more desktops in WinSta0 as well, since any process can call CreateDesktop and create new desktops.

Let’s move on to the desktops associated with non-interactive window stations: these are usually related to a service.  The system creates a window station in which service processes that run under the LocalSystem account are started. This window station is named service-0x0-3e7$. It is named for the LUID for the LocalSystem account, and contains a single desktop that is named Default. However, service processes that run as LocalSystem interactive start in Winsta0 so that they can interact with the user in Session 0 (but still run in the LocalSystem context).

Any service process that starts under an explicit user or service account has a window station and desktop created for it by service control manager, unless a window station for its LUID already exists. These window stations are non-interactive window stations.  The window station name is based on the LUID, which is unique for every logon.  If an entity (other than System) logs on multiple times, a new window station is created for each logon.  An example window station name is “service-0x0-22e1$”.

A common desktop heap issue occurs on systems that have a very large number of services.  This can be a large number of unique services, or one (poorly designed, IMHO) service that installs itself multiple times.  If the services all run under the LocalSystem account, then the desktop heap for Session 0\Service-0x0-3e7$\Default may become exhausted.  If the services all run under another user account which logs on multiples times, each time acquiring a new LUID, there will be a new desktop heap created for every instance of the service, and session view space will eventually become exhausted.

Given what you now know about how service processes use window stations and desktops, you can use this knowledge to avoid desktop heap issues.  For instance, if you are running out of desktop heap for the Session 0\Service-0x0-3e7$\Default desktop, you may be able to move some of the services to a new window station and desktop by changing the user account that the service runs under.

 

Wrapping up

I hope you found this post interesting and useful for solving those desktop heap issues!  If you have questions are comments, please let us know.

 

- Matthew Justice

 

[Update: 7/5/2007 - Desktop Heap, part 2 has been posted]

[Update: 9/13/2007 - Talkback video: Desktop Heap has been posted]

[Update: 3/20/2008 - The default interactive desktop heap size has been increased on 32-bit Vista SP1]

 

Leave a Comment
  • Please add 3 and 7 and type the answer here:
  • Post
  • Many thanks ntdebug for both the excellent post and the quality response(s).  Our solution was to "don't do that" -- we will avoid running so many sessions.  Our heaps were very small percentages so we could have tweaked the values but we were concerned because the server runs SQL Server under a user account (for security reasons) and we didn't want to cause a problem with SQL Server.  In our particular case we were running multiple instances of services that were nearly identical; we rewrote the software to run as a single service and all is well.  Thanks again!

  • Great article.

    One question. I'm running a server with a lot of services running under LocalSystem. The non-interactive desktop-heap size is 512 Kb. All the space is in use, so I should allocate more space for non-interactive desktop heap.

    What are the concequenses?

    I'm not near the limit of 48 Mb, so that's not an issue, but are there any risks (performance wise or so)?

  • Erres,

    I’m glad you enjoyed the article.  The main concern with increasing the sizes of the non-interactive desktop heaps is exhaustion of session view space.  Otherwise increasing the desktop heap size should not adversely affect your system.  Keep in mind that increasing the 512KB value will increase the heap size of all the non-interactive heaps, not just the one for LocalSystem services.

  • What controls size for

    WinSta0\Disconnect    and

    WinSta0\Winlogon  desktop heap?

  • Leonard - The disconnect and winlogon desktop heaps both have a fixed size.  On 32-bit Windows the winlogon desktop heap is 128 KB, and the disconnect desktop heap is 64 KB.  On 64-bit Windows the sizes are increased by 50%, making the winlogon desktop heap 192 KB, and the disconnect desktop heap 96 KB.

  • [Moderator’s note: The following is an excerpt]

    Thanks a MILLION for this information, I finally was able to solve the problem of running out of desktop heap (of course I didn't know that was the cause until I read this post)!  For the last 10 years, I have been running a mix of mostly NT4 (and some Win2K) and I run my workstation for approx 3-6 months at a time between reboots, and typically 50 windows open on the task bar.  Nothing I searched for could solve this problem...

    With your help in this article, I loaded dheapmon and found that every time my malfunction occurs, I'm at 99.9% desktop heap usage.  I increased my Desktop Heap from 3072 to 4096 and it has solved my problems....

    From this eccentric power user... I give you a thousand thanks!

    Josh Straub

  • [Moderator’s note: The following is an excerpt]

    2 questions, Is there any way to map the winstation name back to the domain account that is running the service? And is a reboot required for changes to the non-interactive heap to take effect?

  • Larry,

    The windowstation names that are of the form “Service-0x0-xxx$” are based on the LUID for the logged on user.  I’m not aware of a way to map that value back to a name for a domain user.  Although several local accounts have static LUID values, as defined in the Platform SDK in winnt.h...

    #define SYSTEM_LUID                     { 0x3E7, 0x0 }

    #define ANONYMOUS_LOGON_LUID            { 0x3e6, 0x0 }

    #define LOCALSERVICE_LUID               { 0x3e5, 0x0 }

    #define NETWORKSERVICE_LUID             { 0x3e4, 0x0 }

    To answer your other question: yes, a reboot is required for changes to the size of the desktop heaps (the SharedSection settings) to take effect.

  • Hi we have similar problem on one of our client machines. With default settings for SharedSection=1024,3072,512. When we get out of memory we are at 96.5% heap usage. If we increase Desktop Heap size by 512, do we have to reduce the other numbers?

    Thank you for the answer

  • Lev – If you increase the size of any of these values, you will use more session view space.  Typically an increase of 512KB won’t require any additional tweaking.  I’m not sure if you are planning on increase the interactive desktop heap size (second parameter) or the non-interactive desktop heap size (third parameter).  Increasing the non-interactive heap size often has a larger impact overall, since for session 0 there are multiple non-interactive desktops, and each one will increase in size.  On a typical client machine I wouldn’t expect an increase of 512KB to either the second or third value to be problematic.

  • Hi,

    This is a great article and it makes things much clearer.  You state this is all true when not running with the /3Gb switch.  I notice that regardless what the setting is in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems, when enabling the /sBd switch the heapsize for Service-0x0-3e7$\Default is limited to 128.  When I remove the 3 Gb switch it goes to the set value 2048.  At some instances we are required to run the 3Gb switch as we are running a large database and we hit the 2Gb limit.  Is this value of 128 "tunable" at all?

    Thanks again for this great article,

    Richard

  • For you guys who have messed with the "desktop heap" settings....

    I need you help. I generally have about 20+ windows open on my XP system, which has 1 gig of ram in it.

    I changed the middle setting for the desktop heap, following the info from here: [url]http://www.techarp.com/showarticle.aspx?artno=238&pgno=1[/url]

    This has helped, but now it seems I'm starting to have the same problem again, (not being able to open any new programs or windows, when I have 20+ open already).

    1) Can you tell me what is the best setting for me? What is the max I can go on the heap? This system is used by only one person, me.

    2) What should have my Virtual memory settings at? I have it at 500min/500 max, right now.

    I just want to be able to open more windows

  • Thanks for this great article!  Could there be other causes for this problem of services failing to start and returning the 0xc0000142?  It could be I am missing something but the output from the dheapmon tool on a Windows 2000 system with this problem does not seem to reveal a problem.  Am I missing something?

    C:\kktools\dheapmon8.1\x86>dheapmon -l

    Desktop Heap Information Monitor Tool (Version 8.1.2925.0)

    Copyright (c) Microsoft Corporation.  All rights reserved.

     Dheapmon - Driver loaded successfully

    C:\kktools\dheapmon8.1\x86>dheapmon.exe

    Desktop Heap Information Monitor Tool (Version 8.1.2925.0)

    Copyright (c) Microsoft Corporation.  All rights reserved.

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

     Session ID:    0 Total Desktop: (  7296 KB -    6 desktops)

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

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

     WinSta0\Default                    3072             10.5

     WinSta0\Winlogon                    128              4.0

     Service-0x0-3e7$\Default           1024              9.9

     SAWinSta\SADesktop                 1024              0.2

     Service-0x0-15337$\Default         1024              0.6

     Service-0x0-16c98$\Default         1024              0.6

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

    C:\kktools\dheapmon8.1\x86>

  • Richard,

    I’m glad you found the article helpful.  The behavior you are seeing with 3GB is the result of the following:

    1. When booting non-3GB, the size of session view space is controlled by the SessionViewSize registry value.

    2. When 3GB is enabled, the size of session view space is fixed at 20MB.  This is likely smaller than the value specified in the SessionViewSize registry value.

    3. During the initialization of the window manager, an attempt is made to reserve enough session view space to accommodate the expected number of desktops heaps for a given session.  The size of each heap is calculated using the registry values from the SharedSection string.

    4. If this attempt fails, then the window manager falls  back to a pair of “safe” sizes for desktop heaps (512KB for interactive, 128KB for non-interactive) and tries to reserve session space again, using these smaller numbers.  This ensures that even if the registry values are too large for the session view space size, the system will still be able to boot.

    In your scenario, the smaller desktop heap size is used because (a) 3GB requires that the size of session view space is smaller than normal, and (b) the smaller size of session view space cannot accommodate the larger non-interactive desktop heaps.  That is to say, the window manager doesn’t totally ignore the SharedSection registry string, it evaluates it in context of the size of session view space and the specified desktop heap sizes.  When you run into this problem, the 128KB value is fixed, because it is last-resort option that is used to make sure the system boots.  However, you may be able to reduce the 2048 value to something less, and still get larger desktop heaps, even while running 3GB.

  • Jason,

    I suggest you use dheapmon to verify if you are running into a desktop heap problem or some other problem.  The maximum interactive desktop heap size that you can use depends on the size of session view space on your system and how fully session view space is utilized by other allocations (non-interactive desktop heaps, GDI allocs, etc).  As far as virtual memory goes, a general rule of thumb is set your page file size to 150% of your physical memory.

Page 2 of 7 (101 items) 12345»