Hvordan kan jeg finde den nøjagtige mængde fysisk hukommelse på Windows x86-32bit ved hjælp af Perl eller et andet sprog?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har brug for at vide, hvor meget fysisk hukommelse en Windows-maskine har, ved at bruge Perl.


Jeg har forsøgt at bruge Win32 :: SystemInfo. Men dette modul angiver følgende advarsel: [4]



  På Intel x86-computere med mere end 2 GB og mindre end 4 GB hukommelse, vil MemoryStatus-funktionen altid returnere 2 GB til TotalPhys. Tilsvarende, hvis den samlede ledige hukommelse er mellem 2 og 4 GB, vil AvailPhys afrundes ned til 2 GB.



Så på en maskine, der har 2-4 GB fysisk hukommelse, får jeg et falsk svar.


Er der en måde at få den rigtige mængde fysisk hukommelse på? Måske et andet modul? Eller direkte ved hjælp af Win32 :: API? [5]


Rediger: Fra bemærkningerne folk gav her, ser det ud til, at begrænsningen er i Win32 API, og ikke specifik for Win32 :: SystemInfo. OS gør dog nøjagtigt , hvor meget fysisk ram er tilgængelig, så der skal være en måde at udtrække disse oplysninger på. Hvis ikke i Perl så måske på et andet sprog? [6]

Bedste reference


Som det fremgår af kommentarerne, er dette et problem med GlobalMemoryStatus, da det kan returnere svar op til 2 GB. Og GlobalMemoryStatusEX, som løser dette problem med 2GB-grænsen, men kun virker på 64 bit systemer (så vidt jeg kan fortælle). [7] [8]


Til sidst bruger jeg følgende Perl-kode, der bruger Win32 :: OLE og WMI-klassen Win32\_PhysicalMemory, som returnerer den korrekte mængde fysisk hukommelse, selv på 32bit-systemer: [9]


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 
";
    return $total\_capacity\_in\_mb;
}

Andre referencer 1


Jeg kan kun antage, at advarslerne, der deltager i Win32::SystemInfo s resultater, også tillader overholdelse af de rå Win32 API-opkald, da Perl i sig selv slet ikke har noget problem med at håndtere sådanne store tal. I så fald ser muligheden for at udtrække præcise oplysninger lidt ud dystre.


Jeg har også hørt i forbifarten, at de nuværende 32-bit versioner af Windows kun kan bruge omkring 3,2 GB RAM på en maskine, der har>=4Gb installeret, hvilket kan være hearsay, men hvilke jibes med begrænsningen er i API'en selv.

Andre referencer 2


Denne information kan hentes fra WMI eller ved hjælp af SNMP, hvis du vælger at aktivere SNMP i den boks, den kører på. For WMI har jeg ikke et Perl eksempel offhand, men for et VBScript eksempel se nedenfor.


Ref: http://www.microsoft.com/technet/scriptcenter/guide/sas\_wmi\_dieu.mspx[10]


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


Testet på mit XP-system, og det henter de ønskede resultater (kun 1,5 GB RAM her, undskyld). Jeg er helt sikker på, at der også er WMI-grænseflader til Perl, hvis du vil holde fast ved Perl. Hvis SNMP er en mulighed, kan den samlede fysiske hukommelse også hentes fra SNMP ved hjælp af et af Perl SNMP-biblioteker.


REDIGER : Bare bemærket @Mr. Muskrats kommentar til Microsoft KB http://support.microsoft.com/kb/274558 - åbenbart den adfærd du ser med Perl er en begrænsning af Win32 API-opkaldet, så du kan ende med de samme resultater med WMI . Desværre har jeg ikke en 2-4 GB RAM-maskine til at prøve dette på at verificere. [11]