Autor Beitrag
paul_swatschina
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mo 10.03.08 11:02 
hallo alle.

folgende sache:
ichh programmiere gerade an einem rechenprogramm herum, mit dem ich daten von gps-satelliten verarbeiten will..
diese daten werden in ascii-files im internet angeboten zum download.
ein file hat ca. 6MB.
und ich brauche eigentlich alle infos aus dem file.
dazu lese ich zeilenweise ein und lade alles in ein dynamisches array.
jedes feld ist wiederum ein record aus allerlei komponenten(datum,messung,signalstärke...)

das problem ist nun dass das alles nur für ein drittel des files funktioniert und dann abstürzt weil der arbeitsspeicher voll ist...

was kann man da machen?
ich brauche halt alle daten und muss sie in integer und float wandeln...

wie kann man auslagern, falls das eine möglichkeit darstellt?

danke an alle,
paul
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mo 10.03.08 11:09 
Hallo und :welcome: in der Entwickler-Ecke!

Das Problem "Arbeitsspeicher wird voll" bei "dynamischen Arrays" liegt meistens daran, dass man irgendwas in dieser Art im Code hat:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
for i:= 0 to GanzViel do
begin
  //...
  Setlength(MeinDynArray, Length(MeinDynArray) + 1);
  //...
end;

Besser wäre so etwas, dann reicht der Speicher in der Regel immer aus.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Setlength(MeinDynArray, GanzViel + 1);
for i:= 0 to GanzViel do
begin
  //...
end;

_________________
We are, we were and will not be.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 10.03.08 11:09 
Hallo und :welcome: !

Auslagern tut Windows automatisch, aber bei einer 6 MiB großen Datei sollte eigentlich der Arbeitsspeicher nicht voll werden, denn soo wenig wirst du ja dann doch nicht haben.
  • Wieviel Arbeitsspeicher verbraucht dein Programm denn (im TaskManager)?
  • Wie sieht dein Record aus?
  • Wie liest du die Datei ein?
  • Kann es sein, dass du dein dynamisches Array jeweils um 1 vergrößerst? Dann liegt da dein Problem. Das darf man nicht machen.
Ohne ein wenig Quelltext kann man da kaum mehr dazu sagen.

// EDIT:
7 Minuten nach der Frage 3 Beiträge mit dem selben Smiley in der selben Minute :D


Zuletzt bearbeitet von jaenicke am Mo 10.03.08 11:10, insgesamt 1-mal bearbeitet
Agawain
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 460

win xp
D5, MySQL, devxpress
BeitragVerfasst: Mo 10.03.08 11:09 
Zunächst mal

:welcome:

im Forum.

Mit was für einem Rechner arbeitest Du denn, 386er :tongue:

Mal im Ernst, 6 MB sind kein Ding, oder hast Du Dich vertan?.
Wir können auch schlecht helfen, wenn Du keinen Fitzel Quelltext zur Verfügung stellst.
Nicht unbedingt ist der RAM erschöpft, sondern es könnte auch sein, dass du Ressourcen reservierst, sie aber nicht wieder frei gibst.

_________________
Gruß Aga
paul_swatschina Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mo 10.03.08 11:24 
hallo leute!

danke für eure schnellen anmerkungen.

folgende infos erst mal:
- ich habe 480MB RAM
- ja ich erweitere mein array immer um 1. das liegt daran, dass ich beim einlesen nicht weiss wie viel es werden. die datei beinhält messungen eines gps-receivers. der alle 10sekunden unterschiedlich viele messungen zu eben so vielen satelliten wie vorhanden sind macht. mein jeweiliger record besteht aus datum (jmd hms)in integer, messungen (je 5 mal float), signalstärke(je 5 mal integer), satelliten name (string)...
- der speicher wird bei ca. 50MB voll. das versteh ich auch nicht ganz, wenn ich doch 480 habe...

ich könnte nun das ganze so umkrempeln, dass das programm zuerst alles durgeht und zählt, und dann noch einmal alles zum einlesen durchgeht.
das hatte ich natürlich bei der entwicklung als ineffizient erachtet...

ist es vielleicht ein problem, dass ich die ascii-zeichen immer zu integer und float umwandle - und dadurch aus 6MB auf einmal 60 und mehr werden...?

freu mich schon auf eure nächsten antworten!!!
danke,
paul
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 10.03.08 11:27 
Das Problem: Wenn du das Array um 1 vergrößerst, dann wird ein neues Array erstellt und alles dorthin kopiert. Der Speicherbereich kann nicht einfach vergrößert werden. Und deshalb braucht das Programm immer mehr Speicher.

Nimm einen Delta-Wert:
Vergrößere immer um z.B. 10.000 (je nachdem wieviele Zeilen das sind, es sollte eben nicht zu viel unnötig reserviert werden, aber auch nicht so oft vergrößert) und fülle dann bis der Bereich voll ist, dann vergrößerst du wieder um 10.000 usw. und am Ende verkleinerst du das Array dann auf die tatsächliche Größe.
Dann hast du deutlich weniger Kopieraktionen und das ganze ist sehr viel schneller.
paul_swatschina Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mo 10.03.08 11:31 
ok, es scheint, dass ich mal das mit dem erhöhen um 1 beseitugen muss.
das wir ein wenig dauern...

ich melde mich wieder wenn es so wiet ist.

herzlichen dank einstweilen!!! ihr seid super!!!

ihr könnt natürlich jederzeit noch weitere tipps abgeben,
ich bin programmiermässig der ärgste vollidiot.
es sind also alle anregungen willkommen.

bis dann,
paul
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mo 10.03.08 11:31 
Wenn du nicht weißt, wie groß dein Array sein muss, dann erweitere es Stückweise. Anstelle eines festen Wertes würde ich aber einen festen Faktor vorschlagen, z.B. 1,25 (der wird bei TList/TObjectlist verwendet) oder 1,5. D.h. wenn dein Array voll ist, wird es direkt um 25% oder 50% vergrößert. Als Anfangswert kannst du ja grob schätzen - irgendwie Dateigröße durch erwartete Zeilenlänge oder so ähnlich.

_________________
We are, we were and will not be.
paul_swatschina Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Fr 14.03.08 16:06 
Titel: bin einen schritt weiter
hallo leute!

ich habe jetzt endlich alles so weit umgebaut, und es funktioniert tatsächlich!!!
ich kann alles was ich brauche einlesen!
echt super!
es ist wirklich daran gelegen, dass setlength(xxx,length+1) das problem war.

nun jedoch, mit all diesen daten ergeben sich im weiteren programm-verlauf weitere probleme:
ich habe nun eine dimension der arrays von (derzeit) 46000.
meine berechnungen arebiten mit matrizen, diese habe ich als dynamische arrays eingebaut -
Tmatrix = array of array of extended;
eine matrix zu erzeugen mit 46000x46000 funktioniert nicht,
da heisst es wieder arbeitsspeicher voll. dies konnte ich aber durch eine andere strategie umgehen...
ich muss aber dennoch matrizen mit ca. 46000x4000 erzeugen. und das geht auch nicht...
was kann ich hier tun?
...es wäre gut wenn ich sogar das doppelte zustandebringen könnte
...also setlength(irgendwas,100000,10000)...

ist das zuviel verlangt oder gibts auch da tricks?

danke an alls im voraus!!!
paul
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Fr 14.03.08 16:26 
46.000 mal 46.000 sind 2.116.000.000. Das mal 4 Byte für ein Array-Element sind 8.464.000.000 Byte, oder grob 8 Gigabyte. Das geht erstens nur, wenn man -äh- recht viel Arbeitsspeicher hat und zweitens ein 64-Bit-Windows - bei 32Bit-Windows kann ein Prozess maximal 2GB Speicher belegen.

Lösung: Daten anders organisieren, oder immer nur Teile im Speicher laden.

_________________
We are, we were and will not be.