Seite 1 von 1

Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 23.09.2010 20:20
von Pollux
Um in einem Programm Informationen zur Speichergröße zu ermitteln, wird im Forum auf die API-Funktion 'GlobalMemoryStatus' hingewiesen. Die zugehörige Struktur MEMORYSTATUS enthält aber nur Long-Werte. Daher kann diese Funktion für 64-Bit Windows-Systeme mit mehr als 4 GB Speicher nicht mehr hergenommen werden. Man kann statt dessen die API-Funktion 'GlobalMemoryStatusEx' verwenden, die in der zugehörigen Struktur Quad-Werte enthält.

Ich hantiere zwar erst seit knapp 2 Monaten mit PureBasic, so daß der Begriff 'Beispiel-Code' wohl nicht ganz zutrifft, aber bei mir funktionier folgender Code sowohl unter Win7 64-Bit als auch unter WinXP 32-Bit:

Die Include-Datei 'MyMemoryInfo.pbi':

Code: Alles auswählen

;***********************************************************************************************************************
;* Die 64-Bit-Versionen der neueren Microsoft Betriebssysteme können mehr Arbeitsspeicher unterstützen als die 32 Bit  *
;* Versionen, so daß Long-Werte zur Darstellung der Speichergrößen nicht mehr ausreichen. Die neuere API-Funktion      *
;* 'GlobalMemoryStatusEx" speichert diese Daten daher in einer neuen Struktur MEMORYSTATUSEX. Dieser Code zeigt, wie   *
;* man diese Funktion in PureBasic 4.50 verwendet. Diese Include-Datei funktioniert sowohl als 32 Bit als auch als     *
;* 64 Bit Compilat. Getestet wurde mit Windows XP 32 Bit und Windows 7 64 Bit.                                         *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Umgeschrieben für PureBasic 4.50: Jürgen Priess, 09.2010                                                            *
;***********************************************************************************************************************
EnableExplicit

#Byte =             1 ;Byte
#KB   =          1024 ;KiloByte (1024 Byte = 1 KB)
#MB   =       1048576 ;MegaByte (1024 KB   = 1 MB)
#GB   =    1073741824 ;GigaByte (1024 MB   = 1 GB)
#TB   = 1099511627776 ;TeraByte (1024 GB   = 1 TB)

;In API-Funktion 'GlobalMemoryStatusEx' verwendete MEMORY_STATUS_EX-Struktur
Structure MEMORY_STATUS_EX
  Length.l               ;64 (muß vor aufruf von GlobalMemoryStatusEx initialisiert werden)
  MemoryLoad.l           ;Belegter Speicher in Prozent vom Gesamt-Speichers
  TotalPhys.q            ;Gesamter physikalischer Speicher in Byte
  AvailPhys.q            ;Freier physikalischer Speicher in Byte
  TotalPageFile.q        ;Gesamtgröße der Auslagerungsdatei in Byte
  AvailPagefile.q        ;Freier Speicher der Auslagerungsdatei in Byte
  TotalVirtual.q         ;Gesamtgröße des virtuellen User-Speichers in Byte
  AvailVirtual.q         ;Freier virtueller User-Speicher in Byte
  AvailExtendedVirtual.q ;Ferfügbarer erweiterter virtueller Speicher in Byte (?)
EndStructure

Global MyMemoryStatusEx.MEMORY_STATUS_EX
Global *MyMemoryStatusEx = @MyMemoryStatusEx

Procedure GlobalMemoryStatusEx()
;***********************************************************************************************************************
;* Die Prozedur läd eine vorher initialisierte Struktur mit Informationen zur Speicherbelegung                         *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Wichtig: Das Length-Feld ist vor dem Aufruf der API-Funktion mit 64 zu initialisieren.                              *
;***********************************************************************************************************************
  
  MyMemoryStatusEx\Length = SizeOf(MEMORY_STATUS_EX) ;Initialisieren der Längenangabe
  
  GlobalMemoryStatusEx_(*MyMemoryStatusEx) ;Aufruf der API-Funktion aus der KERNEL32.DLL
  
EndProcedure

Procedure.s BytesUmrechnung(Bytes.q,AusgabeSpeicherEinheit.l=#MB,DezimalStellen=2)
;***********************************************************************************************************************
;* Rechnet die Angegebenen Bytes in die vorgegebene Speichereinheit (#Byte, #KB, #MB, #GB oder #TB) um und gibt das    *
;* Ergebnis als String mit den vorgegebenen Dezimalstellen aus (gegebenenfalls gerundet).                              *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Parameter: Byts:                   Umzurechnende Anzahl Bytes                                                       *
;*            AusgabeSpeicherEinheit: Einer der Konstanten: #Byte, #KB, #MB, #GM oder #TB                              *
;*            DezimalStellen:         Anzahl der Nachkomma-Stellen                                                     *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Return:    Umrechnungs-Ergebnis als Dezimal-Zahl mit den vorgegebenen Dezimal-Stellen als String.                   *
;***********************************************************************************************************************
  
  ProcedureReturn StrD((Bytes/AusgabeSpeicherEinheit),DezimalStellen)
  
EndProcedure
Die Test-Umgebung 'MyMemoryInfoTest.pb':

Code: Alles auswählen

;***********************************************************************************************************************
;* Programm zum Testen der Include-Datei 'MyMemoryInfo.pbi'.                                                           *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Geschrieben für PureBasic 4.50 von: Jürgen Priess (09.2010)                                                         *
;***********************************************************************************************************************
EnableExplicit

IncludeFile "MyMemoryInfo.pbi"

GlobalMemoryStatusEx()

If OpenConsole()
  
  ConsoleTitle("MyMemoryInfoTest")
  
  PrintN("Der Speicher ist zu " + Str(MyMemoryStatusEx\MemoryLoad) + "% belegt.")
  PrintN("Es sind insgesamt " + BytesUmrechnung(MyMemoryStatusEx\TotalPhys,#MB) + " MB physikalischer Speicher eingebaut.")
  PrintN("Davon sind noch " + BytesUmrechnung(MyMemoryStatusEx\AvailPhys,#MB) + " MB physikalischer Speicher frei.")
  PrintN("Die Auslagerungsdatei hat eine Gesamtgroesse von " + BytesUmrechnung(MyMemoryStatusEx\TotalPageFile,#MB) + " MB.")
  PrintN("Davon sind noch " + BytesUmrechnung(MyMemoryStatusEx\AvailPagefile,#MB) + " MB in der Auslagerungsdatei frei.")
  PrintN("Der vom Betriebssystem bereit gestellte virtuelle Adressraum ist " + BytesUmrechnung(MyMemoryStatusEx\TotalVirtual,#MB) + " MB.") 
  PrintN("Davon sind im virtuellen Adressraum noch " + BytesUmrechnung(MyMemoryStatusEx\AvailVirtual,#MB) + " MB frei.")
  PrintN("Der erweiterte virtuelle Speicher ist " + BytesUmrechnung(MyMemoryStatusEx\AvailExtendedVirtual,#MB,0) + " MB gross.")
  
  PrintN("")
  PrintN("===> Druecken sie Return zum Beenden.")
  Input()
  
  CloseConsole()
  
EndIf

End
Unter dem 64-Bit System läuft der Code sowohl als 32- als auch als 64-Bit Compilat.

__________________________________________________
Doppel-Thread gelöscht und Code-Tags hinzugefügt
23.09.2010
RSBasic

Re: Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 23.09.2010 20:32
von sibru
Willkommen im Forum !

Kann Funktion grad nicht prüfen, find´s trotzdem toll: Die Dokumentation ist ausführlich, da können sich
viele alte PB-Hasen mal ´ne Scheibe abschneiden... (lieber zu viel als gar nix).

Viel Spaß noch mit PB...

Re: Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 23.09.2010 22:08
von GPI
Klappt hier (wobei "Der erweiterte virtuelle Speicher ist " bei mir 0 ergibt - was ist das überhaupt?).

KLeine Anmerkung: Einige Win2000 Server-Versionen konnten mehr als 4GB Ram verwalten. Frag mich nicht genau wie, vermutlich stückeln die das irgendwie in 4GB stückchen.

Re: Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 24.09.2010 00:09
von Pollux
Hallo GPI

Der 'erweiterte virtuelle Speicher' ist bei mir auch gleich 0 - offenbar gibt es den auf meinem Rechner auch nicht. Ich habe im Internet gesucht, was das sein soll, aber nichts gefunden.

Da ich ein altes Fossil aus der Computer-Steinzeit bin, kenne ich aber noch die Begriffe 'extendet' und 'expendet' Memory. Damals konnte man die 1 MB ( !!! ) Grenze vom alten DOS durch zusätzliche Hardware (Quadboard) überwinden. Beim 'extended' Memory konnte die zusätzliche Hardware den Adressbereich oberhalb von 1 MB ansprechen. Beim 'expendet' Memory hat es einen Mapping Bereich unterhalb der 1 MB gegeben in den stückchenweise Teile des zusätzlichen Speichers eingeblendet wurden. Ich vermute mal wie sie auch, daß es sich bei dem 'extended virtual Memory' um was Ähnliches handelt.

Re: Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 24.09.2010 07:09
von Thorium
Pollux hat geschrieben:Beim 'expendet' Memory hat es einen Mapping Bereich unterhalb der 1 MB gegeben in den stückchenweise Teile des zusätzlichen Speichers eingeblendet wurden.
Das gibt es auch heute noch in ähnlicher Form für 32bit Systeme mit mehr als 4GB RAM.
Die Namensgebung "virtueller Speicher" ist sowieso mehrdeutig, da mit virtueller Speicher einmal der virtuelle Adressraum eines Prozesses gemeint ist und andererseits wird auch das nutzen der Festplatte als RAM als virtueller Speicher bezeichnet.

Re: Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 24.09.2010 07:10
von ts-soft
Virtueller Speicher wird auch korrekt angezeigt! (win7 x64)
Wenn dort nichts angezeigt wird, liegt das daran, das 1998 mal ne Zeitschrift schrieb:
deaktiviere die Auslagerungsdatei wenn Du genug RAM hast.
Das dies auf aktuellem Windows keinerlei Geschwindigkeitsvorteile mehr bringt,
lediglich eine Selbstkrastation des Systems darstellt, begreifen nur die wenigsten.

Wer also 0 angezeigt bekommt, hat lediglich den falschen Tipp irgendeiner Zeitschrift
befolgt und die Auslagerungsdatei deaktiviert :mrgreen: (der möge dann jetzt auch
ins Wasser springen :mrgreen: )

Gruß
Thomas

Re: Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 24.09.2010 07:57
von GPI
du liegst völlig falsch. Die Auslagerungsdatei wird ja erfast. Nur der erweiterte virtuelle Speicher - da steht null.

Ich hab bei mir auch eine Auslagerungsdatei erstellt - das Win7 ist neu aufgesetzt.

Vielleicht liegts auch daran, das ich Win7 und 64Bit, keine Ahnung.

Re: Speicherbestimmung bei mehr als 4 GB RAM unter Windows

Verfasst: 24.09.2010 16:09
von ts-soft
Hab ich wohl nicht richtig aufgepaßt (wie so oft :mrgreen: )
Der erweiterte virtuelle Speicher ist bei mir auch 0.
Weiß jetzt aber auch gar nicht, wie oder wo der entsteht.
Ich denke mal, das hat was mit dem normal nicht nutzbarem Speicher
zu tun, wenn dieser per Startparameter verändert wird. Sollte also
nur für 32-Bit Systeme mit 4 oder mehr GB RAM zutreffen.

Vermutung heißt aber nicht Wissen!

Gruß
Thomas