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

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

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

在具有超过2 GB和less于4 GB内存的Intel x86计算机上,MemoryStatusfunction将始终为TotalPhys返回2 GB。 同样,如果总可用内存在2到4 GB之间,则AvailPhys将向下舍入为2 GB。

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

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

编辑:从人们给这里的评论,它看起来像在Win32 API的限制,而不是特定于Win32 :: SystemInfo 。 但是,操作系统确切地知道多less物理RAM可用,所以必须有一种方法来提取这些信息。 如果不是在Perl中,那么也许在另一种语言?

正如评论所述,这是一个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; } 

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

我也顺便听说,目前的Windows 32位版本只能在安装了大于4Gb的计算机上使用大约3.2Gb的RAM,这可能是传言,但是在API本身的限制之内。

这些信息可以从WMI中获取,也可以使用SNMP,如果您选择在将要运行的盒子上启用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的WMI接口,如果你想坚持使用Perl。 如果SNMP是一个选项,则可以使用其中一个Perl SNMP库从SNMP获取总物理内存。

编辑 :只是注意到@Mr。 麝鼠的评论关于微软KB http://support.microsoft.com/kb/274558 – 显然你看到的Perl的行为是Win32 API调用的限制,所以你可能最终与WMI相同的结果。 不幸的是,我没有一个2-4GB的RAM机器来验证。