![]() |
Wieviele Daten passen in ein dynamisches Array?
Hallo ihr,
ich arbeite gerade an einem Projekt, wo kurz gesagt ein dynamisches Array of Byte im Laufe einer Analyseroutine mit Daten zur späteren Auswertung gefüllt wird und dabei immer weiter wächst. Das Problem ist nun, dass mein Programm nach ca. 6MB Daten im Array mir eine "Nicht genügend Arbeitsspeicher"-Exception um die Ohren haut. Die Analyseroutine lässt sich mit verschiedenen Optionen fahren, sodass einmal mehr und einmal weniger Daten in das Array kommen. Dabei spielt es keine Rolle, wie lange diese Routine läuft, sondern wieviel Daten das Array bekommt. "Option 1" produziert dabei diesen Fehler. Und die gleiche Routine kann 5min mit "Option 2" (die weit weniger Daten produziert) erfolgreich durchlaufen, ohne Probleme. Ist das normal? Sollte doch eigentlich egal sein, wieviel Daten das Array aufnimmt, solange genügend (virtueller) Speicher zur Verfügung steht, oder nicht? Auf C sind noch 23GB frei, die Auslagerungsdatei ist auf 1,5GB eingestellt, das System hat 512 MB RAM. |
Re: Wieviele Daten passen in ein dynamisches Array?
Hallo,
wie wächst denn Dein Array? Da kann man viel falsch machen. Gruß xaromz |
Re: Wieviele Daten passen in ein dynamisches Array?
Delphi-Quellcode:
Das ist ein Event, der von der TAudioIO-Komponente aufgerufen wird, wenn der interne Buffer (1024 Bytes) voll ist. Die Daten werden an ein Array (FAudioBuffer) in der Klasse angehängt.
// *****************************************************************************
// TAudioScannerSimple // ***************************************************************************** function TAudioScannerSimple.BufferFilled (Buffer: PChar; var Size: Integer): Boolean; var a, b, c: Integer; BitStr3: String; begin for a := 0 to Size do begin BitStr3 := ByteToBitStr (Byte (Buffer[a])); for b := 1 to Length (BitStr3) do inc (FBitsValCount[strtoint (BitStr3[b])]); end; a := Length (FAudioBuffer); SetLength (FAudioBuffer, a + Size); for b := 0 to Size - 1 do FAudioBuffer[a + b] := Byte (Buffer[b]); FBufferFilled := TRUE; end; Edit: Ich seh gerade, dass ich hier einen Fehler hab: for a := 0 to Size do - Es müsste " to Size - 1 do" heissen. Gerade korrigiert und teste es. Edit2: Daran lag es nicht. Bekomme immernoch den Fehler. In der Unit System.pas, procedure DynArraySetLength, Zeile 16273: ReallocMem(pp, neededSize); |
Re: Wieviele Daten passen in ein dynamisches Array?
Also bei mir läuft es ohne Probleme, sogar bis zu 3 Mio. Durchläufen mit einer Puffergröße von 11 (Länge des Array 33000011, Speicherbedarf 36,3 MB, 1024 MB Hauptspeicher) . Allerdings habe ich den ersten Teil auskommentiert, da mit die aufgerufenen Funktionen (ByteToBitStr)nicht vorliegen. Vielleicht müllt dieser Teil etwas zu? Und warum übergibts Du Size als var? Wird doch in der Funktion nicht geändert...
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var i : integer; AudioScanner : TAudioScannerSimple; Size : integer; begin AudioScanner := TAudioScannerSimple.Create; Size := 11; for i := 0 to 3000000 do begin AudioScanner.BufferFilled(pchar('ABCDEFGHIJK'), Size); if i mod 10000 = 0 then begin Label1.Caption := inttostr(i)+'/'+inttostr(length(Audioscanner.Audiobuffer)); Application.ProcessMessages; end; end; end; |
Re: Wieviele Daten passen in ein dynamisches Array?
Ich denke du fährst in das Verwaltungsfragmentierungsproblem des Default-Memorymanagers von Delphi. Lade dir FastMM von Sourceforge und nimm dieses. Damit konnten wir auch ähnliche Probleme lösen. Und unser Programm ist schneller geworden :-)
Aber du solltest dir überlegen ob ein dynamisches Array als interer Buffer die beste Lösung darstellt. Wäre ein TMemoryStream nicht besser? |
Re: Wieviele Daten passen in ein dynamisches Array?
Zitat:
Auch ist vielleicht generell ein Array of byte nicht die tollste Lösung, da hier der Verwaltungsoverhead die "Nutzlast" bei weitem übersteigt. Aber das geht wieder am eigentlichen Problem vorbei. Er hatte gesagt, er erhielte einen Speicherfehler. Dies konnte ich (s.o.) nicht nachvollziehen. Man bräuchte schon die fehlenden Funktionen um den Ablauf vollständig testen zu können. |
Re: Wieviele Daten passen in ein dynamisches Array?
Hallo Mario,
ich würde die buffer segments in einer Liste ablegen. Zusammenschieben kannst du sie immer noch, wenn es denn irgendwann nötig ist. Der Code am Anfang zählt die Nullen und Einsen?
Delphi-Quellcode:
Grüße vom marabu
var
iByte, iBit: Integer; b: Byte; pb: PByte; begin pb := PByte(Buffer); for iByte := 1 to Size do begin b := pb^; for iBit := 1 to 8 do begin Inc(FBitsValCount[b and 1]); b := b shr 1; end; Inc(pb); end; bl.Add(Buffer); // immer 1024 Byte? Result := False; end; |
Re: Wieviele Daten passen in ein dynamisches Array?
Ich würde dir bei vielen Größenänderungen eine Schrittweise änderung ämpfehel und die Tatsächliche Größe extra speichern.
Unter Umständen kann man sons nette Fragmentierungsprobleme bekommen, vorallem bei DelphiMM.
Delphi-Quellcode:
Length(EinArray) wird dann durch MyArray.Size
Type TArray = Record
Size: Integer; Data: Array of Byte; End; Var MyArray: TArray; //Und dann eventuell ein eigenes SetLength (hier wird z.B. auf 64 KB aufgerundet) Procedure MySetLength(Var A: TMyArray; NewSize: Integer); Begin A.Size := NewSize; SetLength(A.Data, (NewSize + $FFFF) and $00010000); End; und EinArray[123] durch MyArray.Data[123] ersetzt. Man kann die Variablen zwar auch einzeln Verwalten, aber zusammen ist es wohl schöner ^^ Obwohl man so nur die SetLength und Length umbauen müßte. (am Array selber ändert sich da ja nichts)
Delphi-Quellcode:
Var ASize: Integer;
AData: Array of Byte; |
Re: Wieviele Daten passen in ein dynamisches Array?
Danke für eure Beiträge.
Warum Size als Var übergeben wird, kann ich nicht sagen. Ist halt die Header-Definition der Prozedur von der Komponente. :D Der Code am Anfang zählt Nullen und Einsen, um ein Verhältnis zwischen ihnen darzustellen, ist aber für den eigentlichen Ablauf nicht wichtig. Hab den Teil gerade mal auskommentiert und lass das Programm nochmal laufen. Ist gerade bei 4MB. Hm, OK, bei 5.710.848 Bytes fliegts mir wieder um die Ohren. Ich werde nun mal den FastMM testen und mich wieder melden. Na mei, mit dem FastMM lief er zum ersten mal durch. Die Endgröße des Puffers war nach dem Durchlauf 10MB. :dance: Danke für den Tip, Bernhard. Werde den guten hier noch etwas Stress-Testen, solange laufen lassen wie es geht. Werde aber auch mal schauen, wie ich den Tip mit der Liste verbauen kann. :cheers: |
Re: Wieviele Daten passen in ein dynamisches Array?
Ach ja, in ein dynamisches Array passen maximal 2 GB - 1 Byte (abgesehn, daß vorher der Speicher ausgehen könnte :roll:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz