AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Speicher läuft voll

Ein Thema von Tonic1024 · begonnen am 9. Nov 2004 · letzter Beitrag vom 17. Nov 2004
Antwort Antwort
Benutzerbild von Tonic1024
Tonic1024

Registriert seit: 10. Sep 2003
Ort: Cuxhaven
559 Beiträge
 
RAD-Studio 2009 Ent
 
#1

Speicher läuft voll

  Alt 9. Nov 2004, 10:54
Hi...

Ich habe ein Moster-Projekt am laufen, dass diverse Daten aus einer datenbank ausliest und dann spezifische Statistiken und andere Auswertungen ermöglicht. Weil von anfang an nicht ganz klar war in welche Richtung die Entwicklung geht habe ich folgendes gemacht: Ich habe die Datensätze in Form einer Tabelle aus einem dynamischen Array of Array of String aufgebaut. Zu diesem Array gehören diverse weitere dynamische Array of String, die darüber auskunft geben wie das Array interprätiert werden soll (steht eine Zahl drin, wieviele nachkommastellen, ist es eine ID (Personalnummer), die mit einem Text (Name der Person) verknüpft werden muss, bedingte Formatierung mit Farben bei Fall X, Y, Z... Soll die Spalte angezeigt werden, etc...).

Auf diese Weise komme ich zu einer stattlichen Ansammlung von dynamischen ein-, zwei- und dreidimensionalen Arrays. Die Arrays werden entweder dynamisch aus einer (mehreren) DLL-deladen oder aus der Datenbank selbst mittels einer TSQLQuerry gezogen.

Wenn ich nun Datensätze abfrage - Können schon mal um die 70.000 sein à ca 150Byte (plus die ganzen Referenz-Arrays), ist aber seltener - dann läuft der Speicher mit bis zu 150MB voll. Das ist eine Zahl, die ich aus dem Windows Task manager im Reiter Systemleistung gefunden habe. Programm gestartet, Speicherwert notiert, Abfrage abgesetzt, Speicher notiert, defferenz ermittelt.

Puh... Jetzt zu meiner Frage:
wenn ich derart große Abfragen starte sind es zwar eine Menge Daten, die da berechnet werden. Aber 150 MB erscheint mir doch ein 'etwas' zu hoher Wert. Wo könnte dieses Phänomen entstehen? Wie kann ich herausfinden was da den Speicher so aufbläht und an welcher Stelle es geschieht. machen es wirklich die Arrays oder läuft die Querry so voll? Kann das sein?

Dazu kommt, wenn ich nach so einer Hammer-Abfrage eine kleine (normale) absetze, bleibt der Speicherwert auf dieser zahl stehen - erst wenn ich das Programm beende wird er wieder freigegeben... Sagt diese Zahl im Systemleistungsfenster überhaupt etwas aus oder mach ich mich nur selbst verrückt?

Ausserdem kann es bei solchen Mords-Abfragen auch dazu kommen, dass das Programm einen "Fehler in Modul MeinProgramm.exe" ausgibt an Adresse sowiso (ihr wisst schon was ich meine) oder sich mit einer Illegal Pointer-Operation verabschiedet. Das muss direkt mit diesem phänomen zusammenhängen. bei normal dimensionierten Abfragen läuft der Code äusserst stabil...

Ich hoffe ich habe halbwegs rübergebracht was ich meine.

hoffe und warte...

MfG

Tonic
Der frühe Vogel fängt den Wurm, richtig.
Aber wird nicht auch der frühe Wurm vom Vogel gefressen?
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.186 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Speicher läuft voll

  Alt 9. Nov 2004, 11:22
Check mal dein Programm mittels MemCheck, ob du noch Speicherlecks hast.

Für dein 150 MB-Problem (70.000 sein à ca 150Byte = 150 MB Speicherzuwachs): Hast Du irgendwelche Debug-Infos aktiv?
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Tonic1024
Tonic1024

Registriert seit: 10. Sep 2003
Ort: Cuxhaven
559 Beiträge
 
RAD-Studio 2009 Ent
 
#3

Re: Speicher läuft voll

  Alt 17. Nov 2004, 08:05
Für alle die die Bedeutung der Suchfunktion kennen...

Die Lösung zu meinem Problem ist relativ einfach gewesen.

setlength(Daten, length(Daten)+1); Dient dazu ein Array um eins zu vergrößern. Das funktioniert auch wunderbar. Wenn man allerdings das ganze Array so aufbaut - immer um einen vergrößern - und das Array dann echt groß wird, kann dabei der Speicher knapp werden.

Ich erklähre mir das so: Vermutlich muss so ein Array in einem zusammenhängendem Stück Speicher geschrieben werden. Wenn also ein Feld des Arrays 10k groß ist und wir drei Felder haben, so belegt das Array 30k. Wenn nun dieser Block nicht erweitert werden kann auf 40k so wird ein neuer Block im Speicher gesucht, der die 40k aufnehmen kann. Scheinbar wird der alte 30k große Block dabei aber nicht oder nicht sofort freigegeben, so dass wir nun schon 70k Speicher belegen mit Daten, die es überhaupt nicht gibt.

Es ist nur eine vermutung, die sich auf folgenden versuch stützt:

Delphi-Quellcode:
 test:='0123456789';
 for i:=0 to 10000 do
 begin
   setlength(Daten, length(Daten)+1);
   for j:=0 to 10 do
   begin
     setlength(Daten[i], length(Daten[i])+1);
     Daten[i][j]:=test;
   end;
 end;
Diesen Code habe ich aus dem Gedächtnis getippt - könnte sein, dass er Fehlerbehaftet ist aber sinngemäß stimmt er

Wer nun meint, Das Array müsse 1.000.000 Byte groß sein, der irrt. Zumindest nach meiner oben beschriebenen Messmethode.
Fakt ist, es war nicht möglich ein oben beschriebenes Array zu verarbeiten.

Die Lösung war darum recht simpel. Ich habe - relativ aufwendig - die Anzahl der zu erwartenden Datensätze ermittelt und das array gleich in diesen Dimensionen gestaltet. Danach stimmte der Speicherverbrauch mit der (geschätzten) Datengröße weitgehend überein.

Meine Vermutungen basieren auf Beiträge aus der DP, die ich perönlich für Einleuchtend halte. Mag sein, dass dies ein bekanntes Problem ist. Ich habe mir das jedenfalls selbst erarbeitet 8)

MfG

Tonic
Der frühe Vogel fängt den Wurm, richtig.
Aber wird nicht auch der frühe Wurm vom Vogel gefressen?
  Mit Zitat antworten Zitat
Benutzerbild von fkerber
fkerber
(CodeLib-Manager)

Registriert seit: 9. Jul 2003
Ort: Ensdorf
6.723 Beiträge
 
Delphi XE Professional
 
#4

Re: Speicher läuft voll

  Alt 17. Nov 2004, 08:11
Hi!

Ja, die Lösung hast du wohl richtig erkannt.
Es gab da gestern/vorgestern auch einen Thread dazu.

Darin erklärte Luckie, dass das mit dem Speichmanagement von Borland/Delphi zu tun hat und es nicht wirklich berechenbar wäre, wann der Speicher wieder freigegeben wird.

Ciao Frederic
Frederic Kerber
  Mit Zitat antworten Zitat
Benutzerbild von jim_raynor
jim_raynor

Registriert seit: 17. Okt 2004
Ort: Berlin
1.251 Beiträge
 
Delphi 5 Standard
 
#5

Re: Speicher läuft voll

  Alt 17. Nov 2004, 08:13
Erstmal Respekt, das du dir das selber erarbeitet hast. Das deutet daraufhin, dass dich Delphi-Interna interessieren. Hast also die Besten Vorraussetzungen um ein Super Programmierer zu werden.

Das Problem ist allerdings schon lange bekannt. Zum Beispiel hier:

http://www.delphi-source.de/grundlag...hermanager.php

Eine Lösung ist einen alternative Speichermanager zu verwenden.
Christian Reich
Schaut euch mein X-COM Remake X-Force: Fight For Destiny ( http://www.xforce-online.de ) an.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#6

Re: Speicher läuft voll

  Alt 17. Nov 2004, 08:15
Zitat von Tonic1024:
Scheinbar wird der alte 30k große Block dabei aber nicht oder nicht sofort freigegeben
Er wird freigegeben, aber nicht für Windows. Der Delphi Speichermanager puffert die freigegeben Speicherblöcke, um schneller Speicher reservieren zu können, da der Windows Speichermanager dazu schon ein wenig mehr Zeit beansprucht.
Das "Problem" (würde es eher als Mishandlung des Speichermanagers bezeichnen) ist aber nicht nur beim Delphi Speichermanager vorhanden, sondern auch der C/C++ Speichermanager malloc/realloc/free hat das "Problem".
  Mit Zitat antworten Zitat
Delphi_Fanatic

Registriert seit: 24. Mär 2004
201 Beiträge
 
#7

Re: Speicher läuft voll

  Alt 17. Nov 2004, 08:33
Wenn ich Dich richtig verstanden habe, dann scheinst Du ja die Ergebnismengen ganzer Queries im RAM ablegen zu wollen.
Also da solltest Du Dir vielleicht lieber eine andere Möglichkeit ausdenken. Solche Datenmengen im RAM abzulegen ist
wirklich nicht üblich.
Verarbeite die Daten lieber gleich in der Datenbank.
  Mit Zitat antworten Zitat
Benutzerbild von Tonic1024
Tonic1024

Registriert seit: 10. Sep 2003
Ort: Cuxhaven
559 Beiträge
 
RAD-Studio 2009 Ent
 
#8

Re: Speicher läuft voll

  Alt 17. Nov 2004, 08:59
Das mit dem RAM ist schon so beabsichtigt gewesen... Es handelt sich um ein recht komplexes Auswerte-Tool, das aus Gründen der Handhabbarkeit so gestrickt ist. Wenn ich viel mit dem Server arbeite verursacht das viel Traffic auf dem Netzwerk einen Spürbaren Lag (mehrere Sekunden) bei der Bedienung. Vermutlich ist der Server ganz schön am schuften wenn mehrere Abteilungen "auf den letzten Drücker" alle ihre Monatsabrechnung machen. Auf diese Weise hat jeder Benutzer nur einen einmaligen Zugriff für ein paar Sekunden und arbeitet dann flüssig mit den lokalen Daten im RAM.

Eine wirklich, wirklich komplexe Abfrage (was übrigens nicht die Regel ist) über mehrer Monate (für die dieses Tool ansich auch garnicht gedacht war - aber danach fragt ein User bekanntlich ja nicht) umfasst nun bis zu 17 MB Arbeisspeicher (alles zusammen incl der geladenen EXE-Datei und DLLs u.s.w.) Ich denke, das ist durchaus vertretbar.


Der Thread von Lucki ist an mir vorbeigegangen... Aber ich hatte die Lösung auch schon vor dem Wochenende gefunden. Nur noch nicht gepostet, weil ich mir noch nicht sicher war. Ich hab die DP intensiv durchforstet und denke sie wär mir ins Auge gefallen...

Das mit dem anderen Speichermanager hat mit Sicherheit nicht nur Vorteile... Ich denke, dass hängt von der eigentlichen Aufgabe ab. Bislang bin ich ganz gut hingekommen mit dem Borland-Speichermanager.

MfG

Tonic
Der frühe Vogel fängt den Wurm, richtig.
Aber wird nicht auch der frühe Wurm vom Vogel gefressen?
  Mit Zitat antworten Zitat
Benutzerbild von Shaman
Shaman

Registriert seit: 2. Nov 2003
Ort: Schweiz
407 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Speicher läuft voll

  Alt 17. Nov 2004, 09:10
Zitat von jim_raynor:
Das Problem ist allerdings schon lange bekannt. Zum Beispiel hier:

http://www.delphi-source.de/grundlag...hermanager.php

Eine Lösung ist einen alternative Speichermanager zu verwenden.
Ist auch z.B. ReallocMem davon betroffen? Sonst mach ich mir mal meine eigenen dynamischen Arrays.
Daniel Pauli
Looking for answers from the great beyond
  Mit Zitat antworten Zitat
Benutzerbild von jim_raynor
jim_raynor

Registriert seit: 17. Okt 2004
Ort: Berlin
1.251 Beiträge
 
Delphi 5 Standard
 
#10

Re: Speicher läuft voll

  Alt 17. Nov 2004, 09:22
So weit ich weis benutzt doch gerade das dynamische Array/Strings ReallocMem. Der macht doch genau das. Also neuen Speicher anfordern, Speicher kopieren, alten Speicher "freigeben".

Wenn dann müsstest du zum direkt per VirtualAlloc oder so direkt von Windows Speicher anfordern und wieder freigeben. Aber dann ist es einfacher, einen eigene Speichermanager zu basteln (siehe dazu SetMemoryManager und GetMemoryManager). Um den dann aber gut zu optimieren braucht schon seine Zeit, deshalb kann man auch getrost einen alternativen MemManger verwenden. Viele sind sogar besser als Delphi-Manager, weil sie direkt größere Bereiche von Windows anfordern. Also statt 3 x 10 Bytes wird bei der ersten Anforderung von 10 Bytes zum Beispiel direkt 4096 Bytes angefordert. Ich glaube einfach, dass man verschiedene Testen muss, wenn man auf solche Probleme stösst.
Christian Reich
Schaut euch mein X-COM Remake X-Force: Fight For Destiny ( http://www.xforce-online.de ) an.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz