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:


0 comments:

Post a Comment