Monday, 17 October 2011

Monitoring Desktop Heap Memory and troubleshooting issues (part II)

Now that we know what Desktop Heap Memory is and How works (Monitoring Desktop Heap Memory and troubleshooting issues (part I)), we can extend this functionality and retrieve the Heap size from our Delphi app and even better, create a new desktop with a specified heap size.

To achieve this I am going to use the public API functions introduced in Windows Vista: CreateDesktopEx, which allows the caller to specify the size of desktop heap.And, GetUserObjectInformation that includes a  flag for retrieving the desktop heap size (UOI_HEAPSIZE).

Get Heap Size:
To get the heap size, we just need to invoke the GetUserObjectInformation using the UOI_HEAPSIZE flag:

procedure GetHeapSizeClick();
var
  HDesktop: HDESK;
  UHeapSize: ULong;
  tempDword: DWORD;
begin
  HDesktop := OpenInputDesktop(0, False, DESKTOP_CREATEMENU or
    DESKTOP_CREATEWINDOW or DESKTOP_ENUMERATE or DESKTOP_HOOKCONTROL or
    DESKTOP_WRITEOBJECTS or DESKTOP_READOBJECTS or DESKTOP_SWITCHDESKTOP or
    GENERIC_WRITE);

  GetUserObjectInformation(HDesktop, UOI_HEAPSIZE, @UHeapSize, SizeOf(UHeapSize), tempDword);
  OutputDebugString(PChar('UOI_HEAPSIZE ' + Inttostr(UHeapSize)));
  CloseDesktop(HDesktop);
end;

The output of the string is as follows:
Debug Output: UOI_HEAPSIZE 12288 Process Project1.exe (4224)

Where the value highlighted in bold, is the predefined size of your heap in the SubSystems\Windows registry key.

Create a new desktop with a specific heap size:
Using the CreateDesktopEx or CreateDesktopExW (Unicode):

var
  HDesktopglobal: HDESK;

procedure CreateDesktop();
var
  UHeapSize: ULong;
  tempDword: DWORD;
begin
  try
    HDesktopglobal := CreateDesktopExW('Z', nil, nil, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, nil, 3052, nil);
  except
    on e: exception do
      ShowMessage(SysErrorMessage(GetLastError));
  end;
  if HDesktopglobal <> 0 then
  begin
    GetUserObjectInformation(HDesktopglobal, UOI_HEAPSIZE, @UHeapSize, SizeOf(UHeapSize), tempDword);
    OutputDebugString(PChar('UOI_HEAPSIZE ' + Inttostr(UHeapSize)));
  end;
end;

procedure CloseDesk();
begin
  CloseDesktop(HDesktopglobal);
end;


We can check the result with dheapmon tool:
With more details using dheapmon -v and the looking for 'Z' desktop.


The output of the string is as follows:
Debug Output: UOI_HEAPSIZE 3052 Process Project1.exe (364)


Remember that the Desktop needs to be closed.

Related links:


Sunday, 16 October 2011

Open a list of URLs

Going on with my previous entries, in this post I am releasing a little tool to open a web browser (in this case google chrome) and populate it with a list of stored URLs. This tool would be the culmination of the articles: My first Google Chrome extension (Get all URLs from Google Chrome tabs) and Get Chrome active tab URL using Delphi. And as you know, I love automating and when I am surfing the internet I like keeping track of my URLs and being able to retrieving and saving them easily.

You can download the tool from here. The tool only needs the path to your browser (in my case google chrome) and a list of pre-saved urls (for example the output list from my chrome extension).

The tool looks like this:


And it uses the ShellExecute function from ShellAPI.

Enjoy it!.

Related Links:

Monitoring Desktop Heap Memory and troubleshooting issues (part I)

This article wants to put together a series of interesting articles to monitor the desktop heap memory and finally put forward a little in-house tool to monitor the output of Desktop Heap Information Monitor Tool v8.1 from AireSoft using the algorithm from "capturing output capture" from one of my previous posts.

Installing "Desktop Heap Information Monitor Tool v8.1:
To correctly install the tool (dheapdmp.zip), go to AireSoft web page and follow the installation steps from the web. If an error pops up, follow the guidelines from the following links:
- dheapInst - driver installation error occurred (2).
dheapinst - Driver Installation error occured (124).

If it helps, I got the error "Driver Installation error occured (124)" and I fixed it by changing the compatibility of dheapinst to Windows Server 2003 SP1.

Once installed, if we run dheapmon -l to install the monitor and then again dheapmon, we will see the heap memory information:


More about "Desktop heap memory":
The Desktop Heap Monitor is a tool that examines usage of desktop heap. 

WIN32 subsystem has internal heap area known as "desktop heap." When you run a large number of Windows-based programs, "Out Of Memory" error messages appear when you attempt to start new programs or try to use programs that are already running, even though you still have plenty of physical and pagefile memory available

This behavior can occur if the desktop heap in the WIN32 subsystem is depleted. To fix this problem follow the next workaround :
http://support.microsoft.com/kb/126962/
sourceMicrosoft.


Increasing "Desktop heap memory":

To increase desktop heap memory, we can use the tool "Microsoft Fix It 50496" that will increase the parameters automatically. If you want to fix it manually, you just need to go to the following registry path and tweak it:
- HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems

Where the default values for my windows vista are:

%SystemRoot%\system32\csrss.exe 
ObjectDirectory=\Windows 
SharedSection=1024,12288,512 
Windows=On 
SubSystemType=Windows 
ServerDll=basesrv,1 
ServerDll=winsrv:UserServerDllInitialization,3 
ServerDll=winsrv:ConServerDllInitialization,2 
ProfileControl=Off 
MaxRequestThreads=16



The first SharedSection value (1024) defines the heap size common to all desktops. This includes the global handle table.


The second SharedSection value (12288) controls the size of the desktop heap that is associated with an interactive window station (used for Windows objects). This static value is used to prevent ill- behaved applications from consuming too many resources. Because the desktop heap is mapped into each process' address space, this value should not be set to an arbitrarily high value (as it would decrease performance), but should only be increased sufficiently to allow all the desired applications to run.


The third SharedSection value (512) controls the size of the desktop heap for each desktop that is associated with a "non-interactive" window station.
source : microsoft.

Monitoring Desktop Heap Memory:
As it is quite difficult to monitor, I have developed a little tool that you can download from here, to log every change on the table result.

Just point the tool to the dheapmon executable and press start. Every 10s the output will be scanned and displayed into the component, taking into account the previous value, and if a change occurs it will be displayed in another colour.

Final notes:
Desktop Heap memory is related to "Out of Memory" issues and this article will help you to work with this parameter and how to deal with it and monitor it.

Stay tuned for Part 2, where I will go further with Desktop heap memory using Delphi.
Jordi Corbilla.

Related links:

Saturday, 8 October 2011