Entwickler-Ecke

Sonstiges (Delphi) - RAM auslesen über 2gb?


MephistoFFF - Di 24.02.09 23:34
Titel: RAM auslesen über 2gb?
Hallo! Ich lasse über nachfolgenden Quelltext den RAM auslesen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  Memory: TMemoryStatus;
begin
  Memory.dwLength := Sizeof (Memory);

  GlobalMemoryStatus(Memory);
  Canvas.Font.Name := 'terminal';
  Canvas.Font.Height := 16;
  Canvas.TextOut(1010'Speicher:         ' +
    IntToStr(Memory.dwTotalPhys div 1048576) + ' MByte');
  Canvas.TextOut(1030'Freier Speicher:  ' +
    IntToStr(Memory.dwAvailPhys div 1048576) + ' MByte');
  Canvas.TextOut(1050'Groesse PageFile: ' +
    IntToStr(Memory.dwTotalPageFile div 1048576) + ' MByte');
  Canvas.TextOut(1070'Freier PageFile:  ' +
    IntToStr(Memory.dwAvailPageFile div 1048576) + ' MByte');
end;


Das klappt soweit auch sehr gut, nur eben, dass ich beim RAM-gesamt ( der erste Wert ) nicht über 2047mb komme... ( Ich habe 3gb im PC, welche vom Task-manager auch erkannt werden ) .

Bin für jede Hilfe dankbar.

mfG


ub60 - Di 24.02.09 23:44

Eventuell hilft das: http://www.delphipraxis.net/post729871.html.

ub60


Delete - Di 24.02.09 23:49

Hier gefunden:

http://www.delphipraxis.net/topic111189_globalmemorystatus+bzw+globalmemorystatusex.html&highlight=globalmemorystatus


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
type
  TMemoryStatusEx = packed record
    dwLength: DWORD;
    dwMemoryLoad: DWORD;
    ullTotalPhys: Int64;
    ullAvailPhys: Int64;
    ullTotalPageFile: Int64;
    ullAvailPageFile: Int64;
    ullTotalVirtual: Int64;
    ullAvailVirtual: Int64;
    ullAvailExtendedVirtual: Int64;
  end;

function GlobalMemoryStatusEx(var lpBuffer: TMemoryStatusEx): BOOL; stdcallexternal kernel32;

procedure TForm1.Button1Click(Sender: TObject);
var
  Status: TMemoryStatusEx;
begin
  ZeroMemory(@Status, SizeOf(TMemoryStatusEx));
  Status.dwLength := SizeOf(TMemoryStatusEx);
  GlobalMemoryStatusEx(Status);
  Label1.Caption := 'Total RAM: ' + IntToStr(Status.ullTotalPhys);
  Label2.Caption := 'Verfügbar RAM: ' + IntToStr(Status.ullAvailPhys);
  Label3.Caption := 'Total Pagefile: ' + IntToStr(Status.ullTotalPageFile);
  Label4.Caption := 'Verfügbar Pagefile: ' + IntToStr(Status.ullAvailPageFile);
  Label5.Caption := 'Total Virtuell: ' + IntToStr(Status.ullTotalVirtual);
  Label6.Caption := 'Verfügbar Virtuell: ' + IntToStr(Status.ullAvailVirtual);
end;


MephistoFFF - Di 24.02.09 23:56

user profile iconub60 hat folgendes geschrieben Zum zitierten Posting springen:
Eventuell hilft das: http://www.delphipraxis.net/post729871.html.

ub60


Funktioniert wunderbar :) . Vielen Dank euch beiden :)


jaenicke - Di 24.02.09 23:57

user profile iconMephistoFFF hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
  GlobalMemoryStatus(Memory);                    
Dass das nicht klappt steht auch in der Dokumentation. :roll:
Dokumentation [http://msdn.microsoft.com/en-us/library/aa366586.aspx] hat folgendes geschrieben:
GlobalMemoryStatus can return incorrect information. Use the GlobalMemoryStatusEx function instead.
Und genauer:
Dokumentation [http://msdn.microsoft.com/en-us/library/aa366586.aspx] hat folgendes geschrieben:
On Intel x86 computers with more than 2 GB and less than 4 GB of memory, the GlobalMemoryStatus function will always return 2 GB in the dwTotalPhys member of the MEMORYSTATUS structure. Similarly, if the total available memory is between 2 and 4 GB, the dwAvailPhys member of the MEMORYSTATUS structure will be rounded down to 2 GB. If the executable is linked using the /LARGEADDRESSAWARE linker option, then the GlobalMemoryStatus function will return the correct amount of physical memory in both members.


Die von user profile iconhathor verwendete Methode ist also genau die in der Dokumentation vorgeschlagene richtige Methode. Das hätte ein Blick in die Dokumentation aber schon gezeigt.


MephistoFFF - Mi 25.02.09 00:10

Eine Frage hätte ich doch noch: Wie lass ich das ganze dann in MByte umrechen? Im moment lass ich die ausgabe so berechnen:


Delphi-Quelltext
1:
IntToStr(Status.ullTotalPhys div 1048576)                    


Allerdings fehlt da bei 2gb 1mb und bei 3gb fehlen 2mb...

mfG


jaenicke - Mi 25.02.09 00:13

Die Rechnung stimmt für Mebibyte schon. Welche Zahl steht denn da vor der Division? Vielleicht wäre eine normale Division und Ceil besser.

Ganz genau ist der Wert nicht immer, das ist er aber im Taskmanager z.B. bei mir auch nicht.


AXMD - Mi 25.02.09 09:17

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Ganz genau ist der Wert nicht immer, das ist er aber im Taskmanager z.B. bei mir auch nicht.


Genau ist der Wert sehr wohl, da auf jedem System durch die PCI-Geräte einige MB Speicher reserviert sind, die nicht anderwertig genutzt werden können. Zitat:
http://blogs.technet.com/markrussinovich/archive/2008/07/21/3092070.aspx hat folgendes geschrieben:
[..]Even systems with as little as 2GB can be prevented from having all their memory usable under 32-bit Windows because of chipsets that aggressively reserve memory regions for devices.[..]
und aus dem weiterführenden Beispiel
http://blogs.technet.com/markrussinovich/archive/2008/07/21/3092070.aspx hat folgendes geschrieben:
The physical address range from 7E700000 to FFFFFFFF is reserved by the PCI bus and devices, which leaves a theoretical maximum of 7E700000 bytes (1.976GB) of physical address space, but even some of that is reserved for device memory, which explains why Windows reports 1.97GB.


AXMD