1

我使用一个代码库,其中包含一个计算可用内存量的函数。

对于托管 PC(由 Windows 2008 R2 x64 托管),我有时会看到以一种有趣的方式计算的免费金额。

它被报告为

物理内存:1400/1400 MB(可用/总)

这不可能是真的,因为有几个应用程序正在运行。怎么会这样?

我感兴趣的是这种现象是否指向内存问题。有时我的应用程序在内存有限(如 1400 MB)的 VM 上运行时内存不足。所以当我看到一个错误报告可用内存错误地报告为 1400 MB 时,它真的是零吗?

这是代码

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;

谢谢!雅各布

4

1 回答 1

1

我无法重现您的问题。唯一的区别是对您Result在行中进行的计算进行了一些更改,因为我现在使用的系统上没有 MadExcept(很快就会纠正)。这是我使用的代码:

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;

这是应用程序的输出(下面有任务管理器的物理内存窗格用于比较),在 Windows 7 上的 Windows XP Mode 虚拟机中运行。VM 设置有 1GB 的 RAM,并有这个测试应用程序,任务管理器,和一个正在运行的 Windows 资源管理器实例。(该应用程序是在 Win 7 64 位上用 D2007 编写的,然后复制/粘贴到 VM 并通过在资源管理器中双击启动。)

使用 Task Man bkgrnd 测试应用程序

于 2012-08-06T22:46:18.797 回答