Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Systemressourcen erschöpft (https://www.delphipraxis.net/130352-systemressourcen-erschoepft.html)

stahli 6. Mär 2009 23:43


Systemressourcen erschöpft
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hi,

ich habe eine komplexe Anwendung geschrieben (Turniersoftware) die zur Laufzeit dynamisch tausende Komponenten erzeugt (Spiele, Spieler, Satzergebnisse, Zeittafeln etc.), die Daten anzeigen und Bearbeitungen ermöglichen.

Im Moment gebe ich damit testweise ältere umfangreiche Turnierdaten eines großen Mannschaftsturniers ein und erhalte neuerdings immer wieder die Meldung "Systemressourcen erschöpft".

Kann mir jemand bei einem Lösungsansatz helfen? Im Moment habe ich noch keine wirkliche Idee woran das liegen kann :-(

Die Anzahl der Handels schwankt immer etwas und war auch schon höher als zum Zeitpunkt der Fehlermeldung.
Evtl. hat das Problem auch mit einer Speicherfunktion auf die Festplatte zu tun...

Anbei zwei Screenshots des Systemmonitors.

Kann mir jemand einen Tip geben? Muss ich erzeugte Komponenten auf verdeckten Registerseiten oder nicht benötigte Formulare gleich wieder auflösen?

Danke
Stahli

Luckie 6. Mär 2009 23:48

Re: Systemressourcen erschöpft
 
Gibst du auchnicht mehr bentugte Objekte auch wieder frei? Dies gilt auf für GDI Ressourcen.

stahli 7. Mär 2009 00:21

Re: Systemressourcen erschöpft
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hmm, das kann ich schwer beantworten...

Ein Turnierprojekt ist so etwas ähnliches wie eine DFM. Die TUR-Datei wird geladen und die (massenweise) enthaltenen Datenkomponenten werden erzeugt und geladen.

Dann gibt es verschiedene sichtbare Komponenten, z.B. Designer und Listen, denen die Datenkomponenten zugewiesen werden. Diese erzeugen dann eine passende Anzahl sichbarer Komponenten, die die Daten anzeigen (siehe z.B. Spielerlisten im Bild).

Werden die Daten aufgelöst, werden auch "automatisch" die sichtbaren Komponenten entfernt. Das findet aber nicht statt, solange ich nur ein anderes Register oder Unterformular auswähle.

Wenn die Anzahl der gleichzeitig erzeugten Komponenten das Problem sein sollt könnte ich vielleicht wenigstens nicht gebrauchte Unterformulare auflösen oder Inhalte von ausgeblendeten Registern löschen...
Aber erst einmal würde ich gern genau wissen, wo das Problem genau steckt und wie ich eine "drohende Ressourcenüberschreitung" vielleicht vorher erkennen kann...
-> "Bitte schnell alles speichern, gleich knallts!" - oder so :-(


Und GDI-Ressourcen kann ich im Moment noch nicht recht einordnen. Ach so, jeder Spieler verwaltet aicuh noch ein Bitmap.


Dannke schon mal!

Dunkel 7. Mär 2009 00:40

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
Und GDI-Ressourcen kann ich im Moment noch nicht recht einordnen. Ach so, jeder Spieler verwaltet aicuh noch ein Bitmap.

Genau solche Bitmaps sind/beinhalten GDI-Ressourcen.

Hast Du schon mal FastMM (oder ähnliche Speicher-Profiler) mitlaufen lassen? Anhand deren Log kann man recht gut herausfinden, wo was nicht freigegeben wird.

stahli 7. Mär 2009 00:51

Re: Systemressourcen erschöpft
 
Nein, da habe ich mich noch nicht heran getraut.
Aber da muss ich dann wohl mal durch und sehen, ob ich damit zurecht komme...

Net7 7. Mär 2009 06:58

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
Dann gibt es verschiedene sichtbare Komponenten, z.B. Designer und Listen, denen die Datenkomponenten zugewiesen werden. Diese erzeugen dann eine passende Anzahl sichbarer Komponenten, die die Daten anzeigen (siehe z.B. Spielerlisten im Bild).

Werden die Daten aufgelöst, werden auch "automatisch" die sichtbaren Komponenten entfernt. Das findet aber nicht statt, solange ich nur ein anderes Register oder Unterformular auswähle.

Wenn die Anzahl der gleichzeitig erzeugten Komponenten das Problem sein sollt könnte ich vielleicht wenigstens nicht gebrauchte Unterformulare auflösen oder Inhalte von ausgeblendeten Registern löschen...
Aber erst einmal würde ich gern genau wissen, wo das Problem genau steckt und wie ich eine "drohende Ressourcenüberschreitung" vielleicht vorher erkennen kann...
-> "Bitte schnell alles speichern, gleich knallts!" - oder so :-(


Wie erstellst du zb. die Strings oder Interger-Werte, zur Ansicht deiner Daten? Local oder Global? Ich hatte mal ein ähnliches Problem. Die Aufgabe meines Programm damals war, die Auswertung von ca. 160000 Zeilen IP-Ländercounts. Bei der Vergabe von zb. Stringlists auf localer Ebene hatte ich irgendwann auch Ressourcenmangel. Auf globaler Ebene nicht mehr.

Mfg Net7

mjustin 7. Mär 2009 07:09

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
Kann mir jemand einen Tip geben? Muss ich erzeugte Komponenten auf verdeckten Registerseiten oder nicht benötigte Formulare gleich wieder auflösen?

Um eventuelle Memory Leaks zu erkennen, kann man (afaik bei Delphi 2006 und höher) in der dpr Datei diese Zeilen einfügen. Dann wird eine Zusammenfassung beim Programmende angezeigt.

Delphi-Quellcode:
{$WARN SYMBOL_PLATFORM OFF}
   ReportMemoryLeaksOnShutDown := DebugHook <> 0;
{$WARN SYMBOL_PLATFORM ON}
Falls eine große Zahl nicht freigegebener Objekte angezeigt wird, kann man anhand der angezeigten Klassennamen versuchen, die Ursachen zu finden. Für detailliertere Fehlerprotokolle kann man FastMM4 direkt einbinden und die Codestellen automatisch auflisten lassen, an denen Objekte erzeugt wurden, die nicht freigegeben werden.

stahli 7. Mär 2009 11:15

Re: Systemressourcen erschöpft
 
Liste der Anhänge anzeigen (Anzahl: 1)
@Net7:
Die Daten sind vorwiegend als Eigenschaften in Objekten enthalten.

@mjustin:
Danke! D2006 bringt da ja schon einen eigenen Ansatz mit (siehe Bild).
Ich hätte nicht gedacht, dass mein Problem doch selbst gemacht ist - muss erst mal aufräumen!
Zumindest ist ein Lösung in Aussicht :-)

Verstehe ich das richtig, dass FastMM oder EurekaLog dann darüber hinaus "nur" helfen, die Stelle im Quelltext leichter zu finden?


Danke schon mal für die GRO?E Hilfe!

Stahli

himitsu 7. Mär 2009 11:31

Re: Systemressourcen erschöpft
 
Systemressourcen sind aber kein Speicher (im MemoryManager),

aber die ganzen GDI-Objecte, welche z.B. in einem TBitMap gekapselt sind schon.

Wobei ~780 Bilder doch eigentlich nicht viel sind (dürften doch nicht viel mehr als 800 bis 4000 GDI-Objecte drin stecken :gruebel: und ich dachte soviel bekommt windows noch locker hin)

jaenicke 7. Mär 2009 11:33

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
Danke! D2006 bringt da ja schon einen eigenen Ansatz mit (siehe Bild).
Ich hätte nicht gedacht, dass mein Problem doch selbst gemacht ist - muss erst mal aufräumen!

Oh ja, bei über 700 nicht aufgeräumten Bitmaps und Bitmapimages musst du dich nicht wundern, wenn die Systemressourcen irgendwann erschöpft sind. ;-)

Zitat:

Zitat von stahli
Verstehe ich das richtig, dass FastMM oder EurekaLog dann darüber hinaus "nur" helfen, die Stelle im Quelltext leichter zu finden?

Richtig. Die zeigen dir an wo die entsprechenden Objekte erstellt wurden.

Aber das siehst du ja vielleicht auch selbst bei dir. Entscheidend könnte z.B. sein, wenn du TBitmap castest um es irgendwo als Pointer zu speichern. Denn dabei geht ggf. der Referenzzähler flöten und es wird nicht mehr aufgeräumt.
Das wären neben den Standardfehlern weitere Fallstricke.

// EDIT:
Zitat:

Zitat von himitsu
aber ~780 ist doch eigentlich nicht viel (dürften doch nicht viel mehr als 4000 GDI-Objecte drin stecken :gruebel: und ich dachte soviel bekommt windows noch locker hin)

Naja, das werden ja ggf. noch mehr, wenn das Programm länger läuft. ;-)

himitsu 7. Mär 2009 11:37

Re: Systemressourcen erschöpft
 
keine Sorge ... TBitMap ist ein Object und die haben ja keine Referenzzählung (wobei man diese als Objekte auch eigentlich nicht nach Pointer casten muß, um sie irgendwo abzuspeichern/abzulegen)

jaenicke 7. Mär 2009 12:08

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von himitsu
keine Sorge ... TBitMap ist ein Object und die haben ja keine Referenzzählung

Ja, dafür müssen sie explizit freigegeben werden.
Ich hatte irgendwie gerade Strings im Hinterkopf als ich das geschrieben habe. :gruebel:

stahli 7. Mär 2009 12:16

Re: Systemressourcen erschöpft
 
Ich habe den Übeltäter :-)

Delphi-Quellcode:
procedure TDPerson.ClearPicture;
begin
  if Assigned(FPicture) then // neu eingeführt
  begin
    FreeAndNil(FPicture);
    FPicture := TBitmap.Create;
    DataChanged;
  end;
end;
Um Bilder "zu löschen" habe löse ich das Bitmap auf und erzeuge ein neues (Bitmap.Clear gibt es ja nicht).
Diese Methode wurde auch aufgerufen bevor das Bitmap das erste mal erzeugt wurde :oops:
Jetzt schließe ich das mit Assigned aus.

Das Hauptproblem scheint geklärt :-)

Danke für die Hilfe!

Stahli

Luckie 7. Mär 2009 13:02

Re: Systemressourcen erschöpft
 
Wen du so vile Unterformulare hast, würde ich die auch nicht beim Programmstart alle automatisch erzeugen lassen, sondern zur Laufzeit dynamisch erzeugen.

stahli 7. Mär 2009 13:05

Re: Systemressourcen erschöpft
 
Ja, das mache ich auch.
Ich löse sie dann allerdings nicht wieder auf, da sie immer mal wieder gebraucht werden.
Für den Notfall merke ich mir das als Option vor.
Nach Klärung des Bitmap-Problems läuft allerdings nun alles perfekt! :-)

Luckie 7. Mär 2009 13:07

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
Ich löse sie dann allerdings nicht wieder auf, da sie immer mal wieder gebraucht werden.
Für den Notfall merke ich mir das als Option vor.

Das würde ich dann allerdings als unsauber betrachten. Wenn du sie schon dynamisch erzeugst, dann mach es auch richtig und gib sie wieder frei, wenn sie geschlossen werden.

stahli 7. Mär 2009 13:16

Re: Systemressourcen erschöpft
 
Kurz zu meinem Konzept dazu:

Die Unterformulare diesen der Datenbearbeitung von Komponenten.
VCustom.FormEdit

Die Methode VCustom.Select öffnet weist der Eigenschaft je nach Situation ein Bearbeitungsformular zu, positioniert und öffnet dieses.
Wurde das betreffende Bearbeitungsformular bisher noch nicht benutzt wird es erzeugt (Eigentümer ist die Application).

Das Formular schließt sich i.d.R. automatisch, wenn es deaktiviert wird.

Aufgelöst wird es, wenn die Application beendet wird.

Die Unterformulare werden imnmer wieder benötigt, daher löse ich sie nicht sofort auf und das führt ja (offenbar) auch nicht zu Problemen...

mjustin 7. Mär 2009 14:38

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
@mjustin:
Danke! D2006 bringt da ja schon einen eigenen Ansatz mit (siehe Bild).

Das ist der Leak Report Bildschirm von FastMM4, dem (Open Source) Memory Manager, der von CodeGear in Delphi integriert wurde. Also eigentlich nix eigenes, sondern eher etwas <borg>assimiliertes</borg> :wink: - und für mich eine der besten Neuerungen an Delphi seit Version 7.

stahli 9. Mär 2009 16:05

Re: Systemressourcen erschöpft
 
Also ich habe jetzt FastMM4 installiert und nutze den FullDebugMode.

So habe ich noch einige weitere Fehler gefunden, bei denen ich über Referenzen auf bereits aufgelöste Objekte deren Methoden aufgerufen habe.
Das habe ich vorher gar nicht bemerkt!

Es ist zwar (auch mit dem Textreport) nicht einfach, die betreffenden Fehler aufzuspüren, aber man erhält ein paar gute Anhaltspunkte.

Es ist also bei komplexeren Programmen wohl unbedingt sinnvoll, FastMM oder Ähnliches zu verwenden. Wäre natürlich auch nicht verkehrt, wenn Delphi so eine Speicherkontrolle selbst durchführen würde.

Welche Alternativen gibt es zu FastMM. Was sind die Vor- und Nachteile?

Stahli

Bernhard Geyer 9. Mär 2009 16:11

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
Es ist zwar (auch mit dem Textreport) nicht einfach, die betreffenden Fehler aufzuspüren, aber man erhält ein paar gute Anhaltspunkte.

Hast Du TD32-Debug-Infos aktiv?

Zitat:

Zitat von stahli
Wäre natürlich auch nicht verkehrt, wenn Delphi so eine Speicherkontrolle selbst durchführen würde.

Hat es doch jetzt :-)

mjustin 9. Mär 2009 16:53

Re: Systemressourcen erschöpft
 
Zitat:

Zitat von stahli
Also ich habe jetzt FastMM4 installiert und nutze den FullDebugMode.

Auch sehr empfehlenswert: das FastMM4 Options Interface

http://jedqc.blogspot.com/2007/07/ne...interface.html

Duech die genauen Hinweise zu den damit erreichbaren Optionen (und deren Abhängigkeiten) kann man bei der Analyse noch einiges mehr erreichen.

Wäre nett, wenn so etwas auch in Delphi integriert wäre. Zum Beispiel als Experte :zwinker: ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:03 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