Announcement

Collapse
No announcement yet.

Ressourcenproblem unter Windows 98 und 2000

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

  • Ressourcenproblem unter Windows 98 und 2000

    Meine MDI-Childforms beinhalten sehr viele PageControls mit vielen Componenten, sowohl Standard von Delphi wie auch eingekaufte von Drittanbietern. Unter Windows 98 sowie 2000 gibt es, wenn enigige Forms geöffnet sind, schwerwiegende Ressourcenprobleme. Es erscheint hauptsächlich die Fehlermeldung "Leinwand erlaubt kein Zeichnen mehr". Anschließend ist eine Arbeit des Anwenders in den Forms unmöglich. Unter Windows NT und XP gibt es dieses Ressourcenproblem nicht. Ich habe auch schon versucht über Exceptions wenigstens das Problem abzufangen, aber zumindest EOutOfMemory, EOutOfResources und EOSERROR werden nicht ausgelöst. Unser Hauptanwender aber muß mindestens noch 1 Jahr unter Windows 98 arbeiten. Ach ja, ich habe den Eindruck, dass dieses Problem auch auftritt, wenn nacheinander Forms geöffnet, geschlossen und wieder geöffnet werden, als wenn nicht alle Ressourcen wieder frei gegeben werden. Kann es sein, dass Delphi-Forms beim Close Ressourcen nicht sauber wieder freigeben? Jedenfalls die Abfrage von geschlossenen Forms ergeben danach nie sauber nil?

  • #2
    Ein Objekt ist immer nur ein Zeiger auf einen Speicherbereich, daher bleibt der Zeiger auch nach Free erhalten.<br>
    Das Problem klingt danach als ob irgendeine Komponente den im Canvas gekapselten DC von Windows mit nicht freigibt

    Comment


    • #3
      Häng mal den Memchecker (http://v.mahon.free.fr/pro/freeware/memcheck/) in deine Anwendung. Damit solltest Du sehr einfach Speicherlecks entdecken die auf Delphi-Seite auftreten.

      Folgende 2 Zeilen reichen in der Projektdatei:

      <pre>
      uses
      MemCheck,
      ...

      {$R *.RES}

      begin
      MemChk;
      ...
      end;
      </pre>

      Code-Optimierungen müssen deaktiviert sein

      Comment


      • #4
        Danke für den Tip mit MemCheck, danach konnte ich groß aufräumen.
        Das funktioniert prima.
        Allerdings waren es nur weinige KByte die im Speicher liegenblieben.

        Ich habe jetzt mal die Ressourcenverwaltung unter Windows 98 aktiviert und das öffnen meiner MDI-Forms überwacht. Bei jedem MDI-ChildForm verliere ich ungefähr 40 % System-Ressourcen und dann ist spätestens beim dritten Form Schluß mit lustig. Ich krieg das Ende der Ressourcen aber im Create bzw. FormShow nicht abgefangen. Die Exception "EOSERROR" kommt nur als WIndowsmeldung nicht über Delphi.
        Meistens kann ich den Rechner neu starten.

        Wer kann helfen, wie man den Ressourcenmangel vielleicht beim Öffnen eines MDI-Childforms abfangen und darauf reagieren kann. Oder gibt es irgendwelche Tuningmaßnahmen, um die verfügbaren Ressourcen zu verbessern

        Comment


        • #5
          Heute habe ich versucht den Hauptspeicher von 64 auf 128 und dann auf 256 MB zu erweitern. Dies hatte überhaupt keinen Einfluss auf die Ressourcen in meinem Programm. Nach wie vor ist beim dritten Form Schluß. Kann man der Anwendung bei Start vielleicht mehr Systemressourcen zur Verfügung stellen

          Comment


          • #6
            Den Speicher unter Win98 zu erhöhen bringt nichts, da im Resourcen-Bereich unter Win9x noch diverse 64kByte-Grenzen existieren. Aber das bei jedem MDI-Form 40% Systemresourcen verloren gehen.<br>
            Kannst Du das auch nachvollziehen wenn Du statt deines speziellen MDI-Childs eine "frisches leeres" MDI-Childfenster öffnest. 40% hört sich nach irgendeiner fehlerhaften Komponente an, welche viele Systemresourcen anfordert aber diese nicht mehr freigiebt (Und da kann Memcheck auch nichts mehr machen, da dies ja nicht über den Delphi-Speichermanager läuft). Probier mal mit Memproof zu arbeiten (http://www.automatedqa.com/downloads/memproof.asp). Dies kann wenn mich nicht alles täuscht auch diese Art von "Resourcelöchern" herausfinden

            Comment


            • #7
              Auch MemProof ist ein gutes Tool. Schwerwiegende Ressourcenfehler werden nicht angezeigt. Allerdings läuft beim Öffnen die Zahl Current Size von Ressource Count und Ressource Size lange und unahrscheinlich hoch. Sollte eine 64 KByte-Grenze betroffen sein, warum gehen die Gesamtressourcen von Windows dann dermaßen in den Keller und nicht nur die Ressourcen die der Anwendung zur Verfügung stehen

              Comment


              • #8
                Also, erstmal müssen wir klären was diese "resourcen" sind:
                <li>USER Resourcen sind hauptsächlich Fensterhandles
                <li>GDI Resourcen sind Grafikhandles, wie DC,Font,Bitmap,Pen,Brush usw.

                Für beide dieser Resourcenklassen stehen Tabellen im OS zur Verfügung in die dieses Handles eingetragen sind. Diese zwei Tabellen sind jeweils NUR 64 Kb groß.<br>
                Die Gesamtresourcen gehen davon aus das dem Anwender NUR interessiert wann ein dieser Hauptresourcen ausgehen. Daher nehmen sie den niedrigsten Wert beider Resourcen und dieser stellt die Gesamtresourcen dar.<br>

                So: z.B. stehen für das gesamte OS nur 5 = FÜNF Gerätekontexthandles = DC zur Verfügung. Wird also EIN DC alloziert so hat man bei den GDI Resourcen schon 20% verbraucht.<br>
                Es geht also extrem schnell das man die Resourcen verbraucht, besonders wenn man bei Zeichenroutinen schlampt oder viele Fensterhandles benutzt.<br>

                Schau dir also deine MDI Chlids ganz genau an, oder mach das was Bernhard vorgeschlagen hat.<br>
                <li>1. entferne alle deine MDI Childs.
                <li>2. füge leere/neue MDI Childs hinzu, und vergleiche.
                <li>3. falls jetzt das Problem nicht auftritt dann müssen deine MDI Childs Fehler haben
                <li>4. falls das Problem weiterhin auftritt musst Du dein MainForm überprüfen, evntl. Datamodules usw.
                <li>5. füge nun succesive jedes deiner MDI Childs hinzu (ich meine jedes vom Typ eigenständige) und überüfe
                <li>6. du solltest dann das Form finden das den Fehler verursacht.
                <li>7. deaktivere (per Ausklammern des Sources) jeden Source in diesem MDI Child
                <li>8. nun füge successive jede auskommentierte Sourcezeile wieder ein, und teste<br>

                Gruß Hage

                Comment


                • #9
                  Öffne ich leere MDI-Childs habe ich kein Ressourcenproblem. Kann es sein, daß meine Childforms aufgrund der vielen Controls ( ca. 400 in einem Childform) so ressourcenfressend sind? Schauich mir das unter MemProof an, laufen die LivePointers bei einem Child um ca. 35000 Zähler hoch. Alle anderen Werte sind eigentlich normal. Wer hat die Erfahrung, habe ich zuviel Controls im Child?

                  Viele Grüße

                  Dir

                  Comment


                  • #10
                    400 Controls !!??<br>
                    das ist aber enorm, wenn es alles TWinControls sind und villeicht auch noch TComboBoxen mit Editfeld dann gehen durch ein Child 1200 Windowshandles drauf.<br>
                    Also: Ich weiß ja nicht welcher User bei 400 angezeigten Controls noch durchblicken soll.<br>
                    Auf alle Fälle dürfte sich Dein Problem nun erklärt haben.<br>

                    Gruß Hage

                    Comment


                    • #11
                      Schönen guten Morgen Hagen,

                      mit 400 Controls ist alles gezählt, jedes Label, Panel, Edit, Button, PageControl, Datenmodul mit Query und DataSource u.a.

                      Mir sagte jemand, dass bei TPanel Objecten unter Windows 98 Ressourcenprobleme auftreten sollen?

                      Viele Grüße Dir

                      Comment


                      • #12
                        TPanel scheint für mich sauber zu sein.<br>
                        Das Problem sind halt viele Fensterhandle. Ich habe es noch nie probiert aber ich schätze mal das bei 2000-3000 allzierten Fensterhandles Schluß ist. Für Fensterhandles stehen 2 * 64Kb zur Verfügung. Dies meint aber NICHT 4 Bytes pro fensterhandle sondern das komplette Fensterhandle mit all seinen Daten= Windowsytle/Brush/Fensterprocedure usw. wird in diesen 2*64Kb gespeichert.<br> Das Fensterhandle ist dann nur das "obfuscated" Speicherhandle in diesen Speicherbereich.<br>
                        In D1/16bit hatte ich auch arge Probleme mit zu vielen Fenstern. Abhilfe hat TPageControl mit TPanel pro Page gebracht. Man kann bei unsichtbaren TPanels .ReleaseWindowHandle aufrufen. Dadurch werden alle Fensterhandles inklusive des TPanles freigegeben. Vor dem Sichtbarmachen dieses TPanels muß dann noch .HandleNeeded aufgerufen werden.<br>
                        Aber Vorsicht: mit TMemos/TComboBoxen gibts dann kleinere Probleme. TMemos verlieren ihren Text und TComboBoxen ihr .ItemIndex.<br>
                        Das sind Bugs in Delphi.

                        Gruß Hage

                        Comment


                        • #13
                          Wieder vielen Dank Hagen,

                          werde das mal versuchen. Gestern habe ich noch mit unserem letzten Anwender unter Windows 98 gesprochen. Er wechselt nächstes Jahr auch weg von Windows 98. Ist also alles nur eine Zeitfrage. Ich habe jetzt ins Verfahren eingebaut, dass man die Anzahl maximal zu öffnender Child-Forms festlegen kann. Bei 2 Fenstern müsste es noch funktionieren. Allerdings nur wenn nicht zu viele externe Programme wie Word, Corel und Terminalemulationen laufen. Kann ich im Programm nicht z.B. über einen Timer die Systemressourcen überwachen und entsprechende Warnungen ausgeben? Müsste doch eine Möglichkeit geben, die Ressourcenverwaltung von WIndows warnt ja auch bei 90 % Auslastung.
                          Exception (eigentlich müssten dies EOSERROR oder EOUTOFRESSOURCES sein)habe ich an alle Stellen im Programm ausgewertet, sie werden aber einfach nicht ausgelöst. Vielleicht liegt das ja da dran, dass das ganze Windows zu diesem Zeitpunkt (keine freien Ressourcen) total instabil ist. Meistens kommen bei diesen Systemabstürzen irgendwelche leeren Meldungsfenster. Weisst Du Rat

                          Comment


                          • #14
                            Es gibt keinen Weg dadurch ausser man verhindert das der User so große Formulare bekommt. Statt viele Felder in einzelnen modallosen Fenster in einer MDI Anwendung, eine SDI Anwendung mit aufgeräumten Formularen die unwichtige Detailmasken als Dialoge ausgelagert haben. Die Dialoge kann man dann mit .Release freigeben und somit verbrauchen sie keinerlei Resourcen wenn sie nicht sichbar sind.
                            SDI Formulare "können" Resourcen "auslagern" wenn sie unsichtbar sind. Dies merkt man sehr gut in Win2k.<br>
                            MDI Formulare habe IMMER Fensterhandles dies schreibt das MDI Konzept vor.<br>
                            Auf den MDI Forms mit PageControls arbeiten und eventuell die Handles freigeben.<br>

                            So habe ich das Problem in Griff bekommen, selbst mit MDI Childs.<br>
                            Eine Erkennung der verfügbaren Resourcen ist schwieriger, die Resourcenanzeige greift über Thunking auf 16 Bit Code zu. Nur dort stellt das OS die wichtigen API funktionen zur Verfügung. Der USER Manager unter Win9x ist 16Bit Code !!<br>

                            Gruß Hage

                            Comment


                            • #15
                              Guten Morgen,

                              mit PageControl und auf jedem TabSheet ein Panel mit alClient konnte ich prima austesten, da jedes Child-Form so aufgebaut ist. Mit DestroyHandle habe ich die Handles aller im Augenblick nicht sichtbaren Handles freigegeben und mit CreateHandle bei aktiv werden des TabSheet sie wieder geholt. ReleaseWindowHandle scheint nicht mehr bekannt zu sein in der class TPanel. Für meine User-Ressourcen hatte das vollen Erfolg, die Zahl verringert sich jetzt bei jedem neuen Child-Form nur sehr gering. War ein voller Erfolg. Nur meine Balken für die System-Ressourcen und GDI-Ressourcen wandert leider nach wie vor noch gleich in den Keller. Kann man hierfür so was ähnliches machen?

                              Viele Grüße Dir

                              Comment

                              Working...
                              X