如何使用Perl或任何其他语言在Windows x86-32bit上找到确切的物理内存量?

时间:2009-01-08 10:25:19

标签: windows perl memory-management

我需要知道Windows机器有多少物理内存,使用Perl。

我尝试过使用Win32::SystemInfo。但是,该模块声明了以下警告:

  

在具有2 GB以上且内存小于4 GB的Intel x86计算机上,MemoryStatus函数将始终为TotalPhys返回2 GB。同样,如果总可用内存介于2到4 GB之间,则AvailPhys将向下舍入为2 GB。

所以在拥有2-4 GB物理内存的机器上,我得到一个错误的答案。

有没有办法获得正确数量的物理内存?也许另一个模块?或直接使用Win32::API

编辑:根据人们在此提供的评论,看起来限制在Win32 API中,而不是特定于Win32::SystemInfo。但是,操作系统确实知道 完全 有多少物理ram可用,因此必须有一种方法来提取该信息。如果不是在Perl中,那么可能用另一种语言?

3 个答案:

答案 0 :(得分:2)

正如评论中所述,这是GlobalMemoryStatus的问题,因为它可以返回高达2GB的答案。而且GlobalMemoryStatusEX解决了这个2GB限制的问题,但只适用于64位系统(据我所知)。

最后我使用了以下Perl代码,它使用Win32 :: OLE和WMI类Win32_PhysicalMemory,即使在32位系统上也能返回正确的物理内存量:

use strict;
use warnings;
use English;
use Win32::OLE qw( EVENTS HRESULT in );
use Readonly;

sub get_physical_memory {
    my $machine                         = shift || '.'; # Default to local machine
    my Readonly $WMI_MEMORY_CLASS_NAME  = 'Win32_PhysicalMemory';
    my Readonly $MEGABYTE               = 1024*1024;

    my $WMI = 
        Win32::OLE->GetObject( "winmgmts:{impersonationLevel=impersonate,(security)}//$machine/" ) || die "Could not get Win32 object: $OS_ERROR";
    my $total_capacity                  = 0;

    foreach my $object ( in( $WMI->InstancesOf( $WMI_MEMORY_CLASS_NAME ) ) ) {
        $total_capacity += $object->{Capacity};
    }

    my $total_capacity_in_mb            = $total_capacity / $MEGABYTE;
    print "Total Memory : $total_capacity_in_mb \n";
    return $total_capacity_in_mb;
}

答案 1 :(得分:1)

我只能假设参加Win32::SystemInfo结果的警告也是参加原始Win32 API调用的警告,因为Perl本身在处理如此大的数字时肯定没有问题。在这种情况下,提取准确信息的可能性看起来有点暗淡。

我也顺便听说过,目前32位版本的Windows只能在装有> = 4Gb的机器上使用大约3.2Gb的RAM,这可能是传闻,但其中的限制是API本身。

答案 2 :(得分:1)

如果您选择在其将运行的框上启用SNMP,则可以从WMI或使用SNMP提取此信息。对于WMI,我手边没有Perl示例,但对于VBScript示例,请参见下文。

参考:http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_dieu.mspx

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)
Set colSWbemObjectSet = _
 objSWbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")

For Each objSWbemObject In colSWbemObjectSet
 Wscript.Echo "Total Physical Memory (kb): " & _
 objSWbemObject.TotalPhysicalMemory
Next

在我的XP系统上测试并检索到所需的结果(这里只有1.5GB RAM,对不起)。如果你想坚持使用Perl,我很确定Perl还有WMI接口。如果SNMP是一个选项,则可以使用其中一个Perl SNMP库从SNMP获取总物理内存。

编辑:刚注意到@Mr。 Muskrat关于Microsoft KB http://support.microsoft.com/kb/274558的评论 - 显然你在Perl中看到的行为是对Win32 API调用的限制,因此你最终可能会得到与WMI相同的结果。不幸的是,我没有2-4GB RAM机器试试这个验证。