Windows 可用物理内存的奇怪值

Windows 可用物理内存的奇怪值,windows,winapi,Windows,Winapi,我使用一个包含函数的代码库来计算可用内存量 对于托管PC(由Windows 2008 R2 x64托管),我有时会看到免费金额以一种有趣的方式计算 它被报道为 物理内存:1400/1400 MB(可用/总) 这不可能是真的,因为有几个应用程序正在运行。怎么会这样 我感兴趣的是这种现象是否指向记忆问题。有时,当我的应用程序托管在内存有限(如1400 MB)的VM上时,内存不足。所以,当我看到一个错误报告,可用内存被错误地报告为1400MB时,它真的是零吗 这是密码 function GetMemo

我使用一个包含函数的代码库来计算可用内存量

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

它被报道为

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

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

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

这是密码

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;
函数GetMemoryStatus:正在销毁;
类型
TMemoryStatusEx=记录
dwLength:dword;
德沃德:德沃德;
ullTotalPhys:int64;
ullavalphys:int64;
ulltottalpagefile:int64;
ullAvailPageFile:int64;
ullTotalVirtual:int64;
ullAvailVirtual:int64;
ullavailxendedvirtual:int64;
结束;
var-gmse:function(var-mse:TMemoryStatusEx):bool;stdcall;
ms:tmemory状态;
mse:TMemoryStatusEx;
开始
gmse:=GetProcAddress(GetModuleHandle(内核32),'GlobalMemoryStatusEx');
如果@gmse nil,则开始
mse.dwLength:=sizeOf(mse);
gmse(mse);
结束,否则开始
ms.dwLength:=sizeOf(ms);
全局记忆状态(ms);
mse.ullavalphys:=ms.dwAvailPhys;
mse.ullTotalPhys:=ms.dwTotalPhys;
结束;
结果:=IntToStrExW((mse.ullAvailPhys+$80000)div$100000)+'/'+
IntToStrExW((mse.ullTotalPhys+$80000)分区$100000)+“MB(免费/总计)”;
结束;
谢谢!
雅各布我无法重现你的问题。唯一的区别是在
结果
行中对您正在进行的计算进行了一些更改,因为除了我现在使用的系统之外,我没有任何其他更改(很快就会更正)。以下是我使用的代码:

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;
类型
TMemoryStatusEx=记录
dwLength:dword;
德沃德:德沃德;
ullTotalPhys:int64;
ullavalphys:int64;
ulltottalpagefile:int64;
ullAvailPageFile:int64;
ullTotalVirtual:int64;
ullAvailVirtual:int64;
ullavailxendedvirtual:int64;
结束;
类型
TGlobalMemoryStatusEx=函数(变量mse:TMemoryStatusEx):bool;stdcall;
函数GetMemoryStatus:字符串;
变量
GlobalMemoryStatusEX:TGlobalMemoryStatusEx;
MemStatEx:TMemoryStatusEx;
开始
GlobalMemoryStatusEx:=GetProcAddress(GetModuleHandle(内核32),
“GlobalMemoryStatusEx”);
如果@GlobalMemoryStatusEx为零,则
开始
MemStatEx.dwLength:=sizeOf(MemStatEx);
GlobalMemoryStatusEx(MemStatEx);
结果:=格式(“%d/%d KB(自由/总)”,
[MemStatEx.ullavalphys第1024分部,
MemStatEx.ullTotalPhys第1024册);
结束;
结束;
程序TForm3.FormShow(发送方:TObject);
开始
标签1.标题:=GetMemoryStatus;
结束;
下面是该应用程序的输出(下面是任务管理器的物理内存窗格以供比较),它在Windows7上的WindowsXP模式虚拟机中运行。虚拟机是用1GB内存设置的,并且有这个测试应用程序、任务管理器和一个运行的Windows资源管理器实例。(该应用程序是在Win7 64位上用D2007编写的,然后复制/粘贴到VM中,并通过双击资源管理器启动。)


我无法重现你的问题。唯一的区别是在
结果
行中对您正在进行的计算进行了一些更改,因为除了我现在使用的系统之外,我没有任何其他更改(很快就会更正)。以下是我使用的代码:

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;
类型
TMemoryStatusEx=记录
dwLength:dword;
德沃德:德沃德;
ullTotalPhys:int64;
ullavalphys:int64;
ulltottalpagefile:int64;
ullAvailPageFile:int64;
ullTotalVirtual:int64;
ullAvailVirtual:int64;
ullavailxendedvirtual:int64;
结束;
类型
TGlobalMemoryStatusEx=函数(变量mse:TMemoryStatusEx):bool;stdcall;
函数GetMemoryStatus:字符串;
变量
GlobalMemoryStatusEX:TGlobalMemoryStatusEx;
MemStatEx:TMemoryStatusEx;
开始
GlobalMemoryStatusEx:=GetProcAddress(GetModuleHandle(内核32),
“GlobalMemoryStatusEx”);
如果@GlobalMemoryStatusEx为零,则
开始
MemStatEx.dwLength:=sizeOf(MemStatEx);
GlobalMemoryStatusEx(MemStatEx);
结果:=格式(“%d/%d KB(自由/总)”,
[MemStatEx.ullavalphys第1024分部,
MemStatEx.ullTotalPhys第1024册);
结束;
结束;
程序TForm3.FormShow(发送方:TObject);
开始
标签1.标题:=GetMemoryStatus;
结束;
下面是该应用程序的输出(下面是任务管理器的物理内存窗格以供比较),它在Windows7上的WindowsXP模式虚拟机中运行。虚拟机是用1GB内存设置的,并且有这个测试应用程序、任务管理器和一个运行的Windows资源管理器实例。(该应用程序是在Win7 64位上用D2007编写的,然后复制/粘贴到VM中,并通过双击资源管理器启动。)


我在Delphi代码中遇到了一个错误。32位进程无法获得总内存和可用内存的正确值。MagWMI和OmniThreadsLib中有相应的函数。我不知道;我认为他们无论如何都不应该失败。第一个使用WMI服务,第二个使用WMI服务可能是错误的重要信息。我们公司的一个应用程序也有同样的问题,但我不是Delphi开发人员,我只是想告诉大家,代码中可能有一个bug,它从operatin系统中获取值。你确定“IntToStrExW”(不管是什么)没有欺骗你吗?@Sertac It's madExcept。该函数的作用是避免使用依赖项