Einzelnen Beitrag anzeigen

Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#16

Re: kleines Programm - riesiger Prozess

  Alt 26. Aug 2004, 02:54
Okay, jetzt wirds interessant.
Folgendes kompiliert bei mir noch so gerade eben - ein Element mehr, und das Teil bringt eine AV:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
type
  TDickesDingen = array[0..$FC5AF] of Byte;
var
  Foo: TDickesDingen;
  i: Integer;
begin
  for i := 0 to Length(Foo)-1 do
    Foo[i] := 0;
end;
Das macht 1.033.648 Elemente á 1 Byte, also ziemlich genau 1 Megabyte.
Der Stack ist auf Max. 1.048.576 Byte. Na, was fällt auf?
Ohne Zugriff, also die bloße Deklaration klappt bis 2Gig!

Dann dieses:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
type
  PDickesDingen = ^TDickesDingen;
  TDickesDingen = array[0..$40F2FFF7] of Byte;
var
  Foo: PDickesDingen;
begin
  new(Foo);
end;
Wird auch gerade noch korrekt ausgeführt.

Kombiniert man dies, kann man mit der Schleife tatsächlich durch das Array im 2. Code durchlaufen, da hier ganz offensichtlich nicht der Stack bemüht wird:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
type
  PDickesDingen = ^TDickesDingen;
  TDickesDingen = array[0..$40F2FFF7] of Byte;
var
  Foo: PDickesDingen;
  i: Integer;
begin
  new(Foo);
  for i := 0 to Length(Foo^)-1 do
    Foo^[i] := 0;
end;
Aaaaber: 0..$40F2FFF7 = 1.089.667.064 Byte und das sind 1,015 Gigabyte => Ich habe 1 Gig RAM. Aber das Teil verbrauchte zur Laufzeit nur kurzzeitig > 700MB, und dann rutschte es gewaltig auf ~20 bis 50MB runter, mitten in der Schleife.
(Messung per Taskmanager )

Es müsste ja theoretisch noch ein Gig mehr gehen... Haut aber partout nicht hin, obwohl mein Pagefile auf 4Gig steht.
Auch mit einer 2. Variable dieses Typs und mit new erzeugt führt zu einer "Out of Memory".

Wenn ich mich recht erinnere, dann hatte ich schon mal ein 3-dimensionales statisches Array verwendet, bei dem mir die 2 Gig-Grenze begenete, und ich hatte es dann auf "knapp darunter" verkleinert, und auch damit gearbeitet. Allerdings als globale Variable, und somit ja nicht auf dem Stack, und auch nicht als Pointer mit new, sondern direkt - aber wieso ging das hier jetzt nicht?
(Kann aber auch sein, dass ich mich irre - ist schon etwas her)

Darf also ein Prozess die Größe des vorhadenen RAMs nicht überschreiten, so dass immer die gesamte Prozess rein passt? Dann werden auch immer nur ganze Prozesse ausgelagert?? Wäre doch birnig, oder?

Ich schnall's glaub ich nicht und geh mal besser ins Bett...
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat