2009-01-08 58 views
2

我需要知道多少物理內存的Windows機器,使用Perl。如何使用Perl或任何其他語言在Windows x86-32bit上找到確切數量的物理內存?

我試過使用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中,那麼也許在另一種語言?

+0

既然你有虛擬可用內存,你真的需要知道這個嗎? – Marius 2009-01-08 10:35:31

+2

是的。通常情況下,人們希望儘可能多地使用物理內存(這會提高性能),但不會觸及交換(這絕對會殺死它)。虛擬內存很好,但爲避免許多算法而更好。 – pjf 2009-01-08 11:07:51

+0

它聽起來不像是Win32 :: SystemInfo的限制。有關詳細信息,請參閱http://support.microsoft.com/kb/274558。 – 2009-01-08 15:22:09

回答

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

我只能假設參加Win32::SystemInfo的結果的注意事項也是參加原始Win32 API調用的警告,因爲Perl本身在處理如此大的數量時肯定沒有問題。在這種情況下,提取準確信息的可能性看起來有點黯淡。

我也聽說過目前的32位版本的Windows只能在安裝了> = 4Gb的計算機上使用大約3.2Gb的RAM,這可能是傳聞,但是其限制在於API本身。

1

如果您選擇在將要運行的盒子上啓用SNMP,則可以從WMI或使用SNMP獲取此信息。對於WMI,我沒有提供一個Perl示例,但是對於VBScript示例,請參見下文。

編號:​​

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對微軟KB http://support.microsoft.com/kb/274558的評論 - 顯然你用Perl看到的行爲是對Win32 API調用的限制,所以你最終可能會得到與WMI相同的結果。不幸的是,我沒有一個2-4GB的RAM機器來驗證。

相關問題