Determining process virtual size using delphi
Asked Answered
A

3

6

I have a Delphi program and I'm looking how this program could print its own "virtual size" in a log file, so that I can see when it used too much memory. How can I determine the "virtual size" using Delphi code?

By "virtual size" I mean the value as displayed by Process Explorer. This value can't be displayed by the normal task manager. It is not directly the memory usage of the program but the address space usage. On Win32 a program can not use more than 2 GB of address space.

PS: I'm using Delphi 6 but code/information for other versions should be ok too.

Aurthur answered 16/11, 2011 at 13:13 Comment(1)
On 64 bit Windows, with LARGEADDRESSAWARE, a 32 bit process can use 4GB virtual address space. On D6 you need to switch MM (e.g. to FastMM) to make this work due to bugs in the Borland MM.Changeup
A
10

Thanks to this post which gives hints about how to get a virtual size using C/C++, I was able to write the following Delphi function:

Type
  TMemoryStatusEx = packed record
    dwLength: DWORD;
    dwMemoryLoad: DWORD;
    ullTotalPhys: Int64;
    ullAvailPhys: Int64;
    ullTotalPageFile: Int64;
    ullAvailPageFile: Int64;
    ullTotalVirtual: Int64;
    ullAvailVirtual: Int64;
    ullAvailExtendedVirtual: Int64;
  end;
  TGlobalMemoryStatusEx = function(var MSE: TMemoryStatusEx): LongBool; stdcall;

function VirtualSizeUsage: Int64;
var MSE: TMemoryStatusEx;
    fnGlobalMemoryStatusEx: TGlobalMemoryStatusEx;
begin
  Result := 0;
  @fnGlobalMemoryStatusEx := GetProcAddress(GetModuleHandle(kernel32), 'GlobalMemoryStatusEx');
  if Assigned(@fnGlobalMemoryStatusEx) then
  begin
    MSE.dwLength := SizeOf(MSE);
    if fnGlobalMemoryStatusEx(MSE) then
      Result := MSE.ullTotalVirtual-MSE.ullAvailVirtual;
  end;
end;

It seems to works great for me (Delphi 6, Win XP). There might be an easier solution using GlobalMemoryStatus instead of GlobalMemoryStatusEx but it wouldn't work correctly on systems with more than 2 GB memory.

Aurthur answered 16/11, 2011 at 13:49 Comment(0)
A
6

Process Explorer seems to do it by calling NtQueryInformation but it's also possible to use performance data, see GetProcessVirtualBytes in my answer here.

Arabic answered 16/11, 2011 at 13:44 Comment(2)
+1 Thanks for the quick answer. I have not tried it because I found another way to do it in the meantime, but it seems to be a good solution.Aurthur
@Aurthur Welcome, this method is only necessary when querying external processes. As I said in a comment to your own answer, your solution is the best in case you're just looking for the information about your own process.Arabic
U
1

And for those who already depend on the otherwise excellent Jedi Code Library, you can find the definitions that @Name correcly points out above in the JclWin32 unit.

The actual numbers you need are also broken out as individual functions in the JclSysInfo unit. Just call GetTotalVirtualMemory()-GetFreeVirtualMemory() to do the calculation.

Uel answered 16/11, 2011 at 22:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.