Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm trying to track down a memory leak on a Windows 7 Embedded Panel PC. Using Perfmon I can see that the "% committed bytes in use" grows steadily at a rate of 0.77% per hour when the app in question is running. On Win XP (not embedded) systems with the same conditions it doesn't grow at all.

I'm curious to know how this metric is calculated, with a view to adding my own monitoring and logging code to the app. Using the GlobalMemoryStatus API call I can get back several numbers, but no amount of crunching that I can think of gives me the same % result as Perfmon does when monitoring the "% committed bytes in use" counter.

How can I obtain this parameter?

Update

Sample code for Delphi follows. Just create a form, drop a memo and timer onto it. Tested under Win XP.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type TPerformanceInformation = packed record
    cb                 : DWORD ;
    CommitTotal        : integer;
    CommitLimit        : integer   ;
    CommitPeak         : Cardinal ;
    PhysicalTotal      : Cardinal ;
    PhysicalAvailable  : Cardinal   ;
    SystemCache        : Cardinal ;
    KernelTotal        : Cardinal ;
    KernelPaged        : integer ;
    KernelNonpaged     : Cardinal ;
    PageSize           : Cardinal ;
    HandleCount        : DWORD ;
    ProcessCount       : DWORD ;
    ThreadCount        : DWORD ;
    end ;

    TpPerformanceInformation = ^TPerformanceInformation ;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Memo1: TMemo;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1 ;

function GetPerformanceInfo (
    pPerformanceInformation : TpPerformanceInformation ;
    cb                      : dword) : integer ; stdcall ; external 'psapi.dll' ;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);

var
    Status           : TMemoryStatus;
    PerformanceInfo  : TPerformanceInformation ;

begin
Memo1.Clear ;
Status.dwLength := sizeof(TMemoryStatus) ;
GlobalMemoryStatus (Status) ;

Memo1.Lines.Add (Format ('Total memory used (%%)  : %u',[Status.dwMemoryLoad])) ;

Memo1.Lines.Add (Format ('Physical memory used   : %u',[(Status.dwTotalPhys - Status.dwAvailPhys)])) ;
Memo1.Lines.Add (Format ('Physical memory left   : %u',[Status.dwAvailPhys])) ;
Memo1.Lines.Add (Format ('Total physical memory  : %u',[Status.dwTotalPhys])) ;
Memo1.Lines.Add (Format ('Total physical used (%%): %1.2f',[100.0 * (Status.dwTotalPhys - Status.dwAvailPhys) / Status.dwTotalPhys])) ;

Memo1.Lines.Add (Format ('Total page file        : %u',[Status.dwTotalPageFile])) ;
Memo1.Lines.Add (Format ('Page file used         : %u',[(Status.dwTotalPageFile - Status.dwAvailPageFile)])) ;
Memo1.Lines.Add (Format ('Page file left         : %u',[Status.dwAvailPageFile])) ;
Memo1.Lines.Add (Format ('Page file used  (%%)    : %1.2f',[100.0 * (Status.dwTotalPageFile - Status.dwAvailPageFile) / Status.dwTotalPageFile])) ;

if (GetPerformanceInfo (Addr (PerformanceInfo), Sizeof (TPerformanceInformation)) <> 0) then
    begin
    with PerformanceInfo do
        begin
        Memo1.Lines.Add (Format ('CommitTotal      : %u',[CommitTotal])) ;
        Memo1.Lines.Add (Format ('CommitLimit      : %u',[CommitLimit])) ;
        Memo1.Lines.Add (Format ('CommitPeak       : %u',[CommitPeak])) ;
        Memo1.Lines.Add (Format ('PhysicalTotal    : %u',[PhysicalTotal])) ;
        Memo1.Lines.Add (Format ('PhysicalAvailable: %u',[PhysicalAvailable])) ;
        Memo1.Lines.Add (Format ('SystemCache      : %u',[SystemCache])) ;
        Memo1.Lines.Add (Format ('KernelTotal      : %u',[KernelTotal])) ;
        Memo1.Lines.Add (Format ('KernelPaged      : %u',[KernelPaged])) ;
        Memo1.Lines.Add (Format ('KernelNonpaged   : %u',[KernelNonpaged])) ;
        Memo1.Lines.Add (Format ('PageSize         : %u',[PageSize])) ;
        Memo1.Lines.Add (Format ('HandleCount      : %u',[HandleCount])) ;
        Memo1.Lines.Add (Format ('ProcessCount     : %u',[ProcessCount])) ;
        Memo1.Lines.Add (Format ('ThreadCount      : %u',[ThreadCount])) ;
        end ;
    end ;
end;

end.
share|improve this question

1 Answer 1

up vote 1 down vote accepted

Check out GetPerformanceInfo(). It kicks back commit numbers.

share|improve this answer
    
Hmmmm @Jason - I don't suppose you could point me to how to call this from Delphi? I call it but the structure I pass doesn't get modified and after a few more calls I get an AV. –  rossmcm May 3 '11 at 8:28
    
Worked it out - question edited to provide example program –  rossmcm May 4 '11 at 21:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.