可用物理内存的奇怪值

问题描述:

我使用包含函数的代码库来计算可用内存量。可用物理内存的奇怪值

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

它被报告为

物理内存:1400分之1400MB(免费/总)

这真的不能是真实的,因为几个应用程序在运行。这怎么可能发生?

我的兴趣在于这种现象是否指向记忆问题。有时我的应用程序在内存有限的内存(如1400 MB)上运行时内存不足。因此,当我看到一个错误报告,错误地报告了可用的错误报告为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; 

谢谢! Jacob

+0

这是madExcept代码。你为什么不问madExcept论坛?无论如何,我是否会从你的问题中得出结论,这只发生在虚拟机器内部? – 2012-08-06 16:16:40

+0

我遇到了Delphi代码中的一个错误。一个32位的进程将无法获得全部和空闲内存的正确值。 – 2012-08-06 16:10:25

+0

在MagWMI和OmniThreadsLib中有它的函数。我不认为他们应该失败。第一次使用WMI服务,第二次使用可能是相当重要的信息,以使其错误。 http://www.magsys.co.uk/delphi/magwmi.asp http://otl.17slon.com – 2012-08-06 16:13:51

我无法重现您的问题。唯一的区别是您在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模式的虚拟机中运行1GB的RAM,并且有测试应用程序,任务管理器和单个Windows资源管理器实例正在运行。 (该应用程序被写在D2007在Win 7 64位,然后复制/粘贴到VM并通过双击在资源管理器启动。)

Test app with Task Man bkgrnd

+0

我不能完全看到你要去哪里与此。 – 2012-08-07 07:23:29

+0

不客气,现在我认为是时候清理这些乱七八糟的评论了! ;-) – 2012-08-07 16:55:35

+0

@大卫,完成。 :-)我仍然试图重现这一点,现在海报已经表明它不是一个MadExcept或Delphi问题,但我无法在VirtualBox或带有XP 32位或Win7 64的VirtualPC中这样做。 – 2012-08-08 00:15:05