Reputation: 61
I use a code library that contains a function to calculate the amount of memory avaliable.
For hosted PC's (hosted by Windows 2008 R2 x64) I sometimes see the free amount calculated in a funny way.
It gets reported as
physical memory : 1400/1400 MB (free/total)
Which cant really be true, since several applications are running. How can that happen?
My interest here is whether this phenomenon points to a memory problem. Sometimes my application runs out of memory when hosted on a VM with limited memory like 1400 MB. So when I see a bug report with the available meory wrongly reported as 1400 MB could it be that it really is zero?
Here is the code
function GetMemoryStatus : UnicodeString;
type
TMemoryStatusEx = record
dwLength : dword;
dwMemoryLoad : dword;
ullTotalPhys : int64;
ullAvailPhys : int64;
ullTotalPageFile : int64;
ullAvailPageFile : int64;
ullTotalVirtual : int64;
ullAvailVirtual : int64;
ullAvailExtendedVirtual : int64;
end;
var gmse : function (var mse: TMemoryStatusEx) : bool; stdcall;
ms : TMemoryStatus;
mse : TMemoryStatusEx;
begin
gmse := GetProcAddress(GetModuleHandle(kernel32), 'GlobalMemoryStatusEx');
if @gmse <> nil then begin
mse.dwLength := sizeOf(mse);
gmse(mse);
end else begin
ms.dwLength := sizeOf(ms);
GlobalMemoryStatus(ms);
mse.ullAvailPhys := ms.dwAvailPhys;
mse.ullTotalPhys := ms.dwTotalPhys;
end;
result := IntToStrExW((mse.ullAvailPhys + $80000) div $100000) + '/' +
IntToStrExW((mse.ullTotalPhys + $80000) div $100000) + ' MB (free/total)';
end;
Thanks! Jacob
Upvotes: 1
Views: 1383
Reputation: 125708
I can't reproduce your problem. The only difference is some changes to the calculations you're doing in the Result
line, because I don't have MadExcept on the system I'm on right now (will rectify that soon). Here's the code I used:
type
TMemoryStatusEx = record
dwLength : dword;
dwMemoryLoad : dword;
ullTotalPhys : int64;
ullAvailPhys : int64;
ullTotalPageFile : int64;
ullAvailPageFile : int64;
ullTotalVirtual : int64;
ullAvailVirtual : int64;
ullAvailExtendedVirtual : int64;
end;
type
TGlobalMemoryStatusEx = function (var mse: TMemoryStatusEx) : bool; stdcall;
function GetMemoryStatus : string;
var
GlobalMemoryStatusEX: TGlobalMemoryStatusEx;
MemStatEx : TMemoryStatusEx;
begin
GlobalMemoryStatusEx := GetProcAddress(GetModuleHandle(kernel32),
'GlobalMemoryStatusEx');
if @GlobalMemoryStatusEx <> nil then
begin
MemStatEx.dwLength := sizeOf(MemStatEx);
GlobalMemoryStatusEx(MemStatEx);
Result := Format('%d / %d KB (free/total), ',
[MemStatEx.ullAvailPhys div 1024,
MemStatEx.ullTotalPhys div 1024 ]);
end;
end;
procedure TForm3.FormShow(Sender: TObject);
begin
Label1.Caption := GetMemoryStatus;
end;
Here's the output of the app (with Task Manager's Physical Memory pane beneath it for comparison), running in a Windows XP Mode virtual machine on Windows 7. The VM was set up with 1GB of RAM, and has this test app, Task Manager, and a single Windows Explorer instance running. (The app was written in D2007 on Win 7 64-bit, and then copied/pasted into the VM and started by double-clicking in Explorer.)
Upvotes: 1