Announcement

Collapse
No announcement yet.

Speicherfresser: neues Formular

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Speicherfresser: neues Formular

    Hallo

    Ich arbeite nun schon länger mit Delphi 2007 an einem recht umfangreichen Projekt. Seit ca. 4 Monaten habe ich allerdings extreme Arbeitsspeicher-Probleme auf den Anwender-Geräten.

    Ich habe daraufhin einige Tests ausgeführt.

    Formular1: Ein nacktes (automatisch erzeugtes) Formular mit einem TButton + Click Ereignis.
    Formular2: Ein nacktes (verfügbares) Formular mit 3 Komponenten, IBDatabase, IBTransaction, IBTable.

    Beim Create von Formular2 werden die Database, Transaction und Tabelle geöffnet. Beim Close wird alles wieder geschlossen.

    Beim Click des Button's auf Formular 1 wird folgender Code ausgeführt:
    Code:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      I: Integer;
    begin
      Form2 := TForm2.Create(Self);
      try
        Form2.Show;
      finally
        Form2.Release;
      end;
    end;
    Nun gibt es folgendes zu bestaunen:

    1.) Nach Programmstart läuft das Programm mit 800k im Arbeitsspeicher
    2.) Nach dem ersten Klick werden 740k zusäzlich im Speicher belegt.
    3.) Nach jedem weiteren nur noch zusätzliche 52k - 72k

    Nun meine Frage:

    Wenn ich das ganze eine Stunde lang mache, wird das Programm im Arbeitsspeicher ca. 25MB belegen. Warum wird durch die Zeile
    Code:
    Form2.Release
    nur ein Teil des genutzten Speichers freigegeben?

    Im Internet findet man Anfragen von Leuten, bei denen das Problem auch auftritt, aber nie eine Lösung die wirklich funktioniert. Selbst wenn auf Form2 gar nichts passiert, nur ein leeres Formular, steigt der Speicher stetig an.

    Bei meinem Hauptprogramm mit vielen Masken steigt der Speicher, trotz Freigabe, regelmäßig auf 300 - 800 MB an. Bei ca. 60 Usern pro Terminalserver sind das mal eben hochgerechnet 48GB an Speicherauslast. Da der Server das nicht liefert schmiert das Programm regelmäßig ab. Was nicht gerade zur Zufriedenheit des Users beiträgt.

    Daher meine Hoffnung in diesem Forum jemanden zu finden, der darauf eine Lösung hat.

    Grüße,

    Michael Brotrück

  • #2
    Dass das Formular 2 leer ist stimmt nicht ganz - laut deiner Angabe befinden sich 3 IB-Komponenten darauf. Probiere das Ganze mal ohne diese, bzw. mal nur mit dem Database-Objekt. Vielleicht hat's damit zu tun. Wenn ja, könnte man vielleicht im OnClose der Form2 die entsprechende(n) Komponente(n) explizit disposen.

    bye,
    Helmut

    Comment


    • #3
      Hallo Helmut,

      entschuldige, wenn ich mich schlecht ausgedrückt habe.
      Ich hatte es auch mit leerem Formular geprüft. Gleiches Ergebnis.

      Wir haben es hier auch mittlerweile mit mehreren Delphi Installationen probiert,
      sogar das Betriebssystem haben wir gewechselt.

      Alle Versuche bisher ohne Erfolg.

      Hoffe es ist nun etwas klarer.

      MfG

      Michael

      Comment


      • #4
        Ich werde am Wochenende mal schauen, wie sich das bei mir verhält. Habe derzeit ein D7 unter XP und ein XE unter Win7 laufen (aber gerade ein paar Termine, die ich vorher noch erledigen muss).

        bye,
        Helmut

        Comment


        • #5
          So, habe es jetzt mal getestet. ich kann zunächst mal nicht beurteilen wie gut die Angaben des Taskmanagers sind, aber die Ergebnisse waren wie folgt:

          mit D7 unter XP sprang die Anzeige für den Speicherverbrauch die ganze Zeit zwischen 800 und 1800 Kb herum (auch noch nach 2000 mal Fenster öffnen/schließen). Keine Ahnung, wie man das bewerten kann.

          mit XE unter Windows7 (in einer VMWare) gab es keine sprunghafte Anzeige, da startet das Programm mit 990 Kb und war nach 2000 Fenstern auf 1020 Kb - auch nicht die Welt, aber irgendwie wurde wohl nicht immer alles restlos freigegeben.
          Wenn man da große Masken mit vielen Objekten hat, kann das sicher schlimmer aussehen.

          Tja, da ist guter Rat teuer, habe leider auch keine Idee, was man dagegen machen könnte.

          bye,
          Helmut

          Comment


          • #6
            Es gibt (ich hoffe, bereits ab 2007) die globale Variable ShowMemoryLeaksOnShutdown. Setze diese mal im Hauptprogramm (Projektdatei) auf true, also z.B.

            [highlight=delphi]
            begin
            ShowMemoryLeaksOnShutdown:=True;
            Application.Initialize;
            ...

            end.
            [/highlight]

            Man bekommt dann beim Schließen des Programms einen Hinweis, dass noch soundsoviel TLists, TForms usw. nicht freigegeben wurden. Sollte das bei Dir auch so zu sehen sein, dann steckt schon irgendwo ein Fehler. In der Regel, wie hier schon angedeutet, in den verwendeten Komponenten.

            Grundsätzlich gibt es meiner Meinung nach aber kein Speicherproblem bei Delphi.
            Der von dir gepostete Code ist i.o.
            Wird ein alternativer Speichermanager verwendet (fastmm?). Eventuell kann man aber mal mit fastmm testen, der bietet etwas mehr an Debugging - Funktionen.

            Grüße
            Tino

            Edit: Zur Bekräftigung, dass es imho kein grundätzliches Delphi - Speicherleck gibt:
            Ich habe eine Anwendung, die im 15 - Minutentakt ca. 50 Threads mit Datenmodulen, SQL - Objekten (DevArt), XML - und HTTP - Komponenten (Indy) usw. aufmacht und wieder abräumt. Zwischendurch sogar per OLE Excel - Tabellen befüllt. Die läuft jetzt so ca. 6 Wochen durch und hat noch die gleiche Speicherauslastung wie beim Start. Allerdings in D2009 programmiert.
            Zuletzt editiert von tinof; 23.05.2011, 10:18.
            Ich habs gleich!
            ... sagte der Programmierer.

            Comment


            • #7
              ... Ich habe eine Anwendung, die im 15 - Minutentakt ca. 50 Threads mit Datenmodulen, SQL - Objekten (DevArt), XML - und HTTP - Komponenten (Indy) usw. aufmacht und wieder abräumt. Zwischendurch sogar per OLE Excel - Tabellen befüllt. Die läuft jetzt so ca. 6 Wochen durch und hat noch die gleiche Speicherauslastung wie beim Start...
              Leider sagt das nichts aus. Man kann nur mit einem fehlerhaften Test beweisen, dass es einen Fehler gibt, aber ein Test ohne Fehler bedeutet nicht zwangsweise, dass das Programm fehlerfrei ist.

              Deinen Tipp mit dem LeaksOnShutdown habe ich mal ausprobiert:
              a) heisst richtig ReportMemoryLeaksOnShutdown und das gibt's seit Delphi 2006
              b) mit meinem Delphi XE unter Win7 frisst dieses Testprogramm ganz langsam Speicher, nicht viel aber stetig. Und wenn ich das Programm schließe gibt's keine Anzeige durch das "ReportMemoryLeaksOnShutdown", dass irgendwas offen wäre. Es sieht auch so aus, als würde beim Beenden der gesamte Speicher freigegeben, aber eben erst am Schluß und nicht auch zur Laufzeit.

              bye,
              Helmut

              Comment

              Working...
              X