如何使用 Perl 或任何其他语言在 Windows x86-32bit 上找到确切的物理内存量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/423797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I find the exact amount of physical memory on Windows x86-32bit using Perl or any other language?
提问by Tom Feiner
I need to know how much physical memory a windows machine has, using Perl.
我需要知道 Windows 机器有多少物理内存,使用 Perl。
I've tried using Win32::SystemInfo. However this module states the following caveat:
我试过使用Win32::SystemInfo。但是,该模块声明了以下警告:
On Intel x86 computers with more than 2 GB and less than 4 GB of memory, the MemoryStatus function will always return 2 GB for TotalPhys. Similarly, if the total available memory is between 2 and 4 GB, AvailPhys will be rounded down to 2 GB.
在内存大于 2 GB 且小于 4 GB 的 Intel x86 计算机上,MemoryStatus 函数将始终为 TotalPhys 返回 2 GB。同样,如果总可用内存介于 2 GB 和 4 GB 之间,AvailPhys 将向下舍入为 2 GB。
So on a machine which has 2-4 GB of physical memory, I get a false answer.
因此,在具有 2-4 GB 物理内存的机器上,我得到了错误的答案。
Is there a way to get the correct amount of physical memory? Perhaps another module? Or directly using Win32::API?
有没有办法获得正确数量的物理内存?也许另一个模块?还是直接使用Win32::API?
Edit: From the comments people gave here, it looks like the limitation is in the Win32 API , and not specific to Win32::SystemInfo. However, the OS doesknow exactlyhow much physical ram is available, so there must be a way to extract that information. If not in Perl then maybe in another language?
编辑:从人们在这里给出的评论来看,限制似乎是在 Win32 API 中,而不是特定于Win32::SystemInfo。然而,操作系统确实知道有多少物理内存可用,因此必须有一种方法来提取该信息。如果不是 Perl 那么也许是另一种语言?
采纳答案by Tom Feiner
As stated in the comments, this is an issue of GlobalMemoryStatus, as it can return answers up to 2GB. And GlobalMemoryStatusEXwhich solves this issue of the 2GB limit, but only works on 64 bit systems (as far as I can tell).
正如评论中所述,这是GlobalMemoryStatus的问题,因为它可以返回高达 2GB 的答案。而GlobalMemoryStatusEX解决了 2GB 限制的这个问题,但只适用于 64 位系统(据我所知)。
In the end I'm using the following Perl code, which uses Win32::OLE and WMI class Win32_PhysicalMemory, which returns the correct amount of physical memory even on 32bit systems:
最后,我使用了以下 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;
}
回答by j_random_hacker
I can only assume that the caveats attending Win32::SystemInfo
's results are also caveats attending the raw Win32 API calls, as Perl itself certainly has no problem handling such large numbers. In which case the possibility of extracting accurate information looks a bit bleak.
我只能假设关注Win32::SystemInfo
结果的警告也是关注原始 Win32 API 调用的警告,因为 Perl 本身在处理如此大的数字时当然没有问题。在这种情况下,提取准确信息的可能性看起来有点暗淡。
I've also heard in passing that current 32-bit versions of Windows can only use about 3.2Gb of RAM on a machine that has >= 4Gb installed, which may be hearsay, but which jibes with the limitation being in the API itself.
我还顺便听说当前 32 位版本的 Windows 只能在安装了 >= 4Gb 的机器上使用大约 3.2Gb 的 RAM,这可能是道听途说,但这与 API 本身的限制相吻合。
回答by Jay
This information can be pulled from WMI, or using SNMP if you choose to enable SNMP on the box it will be running on. For WMI, I don't have a Perl example offhand but for a VBScript example see below.
该信息可以从 WMI 中提取,或者使用 SNMP,如果您选择在运行它的机器上启用 SNMP。对于 WMI,我没有临时的 Perl 示例,但对于 VBScript 示例,请参见下文。
Ref: http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_dieu.mspx
参考: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
Tested on my XP system and it retrieves the desired results (only 1.5GB RAM here, sorry). I'm quite sure there are WMI interfaces for Perl as well if you want to stick with Perl. If SNMP is an option, the total physical memory can be obtained from SNMP as well using one of the Perl SNMP libraries.
在我的 XP 系统上进行了测试,它检索了所需的结果(这里只有 1.5GB RAM,抱歉)。如果您想坚持使用 Perl,我很确定 Perl 也有 WMI 接口。如果 SNMP 是一个选项,则也可以使用 Perl SNMP 库之一从 SNMP 获取总物理内存。
EDIT: Just noticed @Mr. Muskrat's comment regarding Microsoft KB http://support.microsoft.com/kb/274558- evidently the behavior you're seeing with Perl is a limitation of the Win32 API call, so you might end up with the same results with WMI. Unfortunately I don't have a 2-4GB RAM machine to try this on to verify.
编辑:刚刚注意到@Mr. Muskrat 对 Microsoft KB http://support.microsoft.com/kb/274558的评论- 显然,您在 Perl 中看到的行为是 Win32 API 调用的限制,因此您最终可能会得到与 WMI 相同的结果。不幸的是,我没有 2-4GB RAM 的机器来尝试验证。