| Autor |
Beitrag |
lightsaver
      
Beiträge: 24
C# (VS 2008 Prof.)
|
Verfasst: Do 17.04.08 20:35
Ich konnte leider nicht so wirklich eine antwort hier über die Suche finden, daher frage ich einfach mal, wie ich bei meinem Programm Speicher freigeben kann.
Hier kurz was zum Programm:
es gibt mehrere Forms, ein projektweites DataSet für die wichtigsten Daten aus der Datenbank und dann in einem Form nochmal zusätzlich ein DataSet was ich immer nur mit den für dieses spezielle Form nötigen Daten fülle. Nennen wir dieses Form einfach mal Form2.
So, wenn ich das Programm nun starte komme ich erstmal zu Form1, welches zur zeit nur ein recht kleines Form mit 3 Buttons ist. Dass ich hier schon ca. 9mb Speicher verbrauche finde ist zwar schon recht viel, scheint aber, nach dem was andere hier geschrieben haben, normal zu sein. So, im weiteren verlauf muss ich erstmal das ProjektDataSet füllen was mich dann mal schnell auf 17mb bringt. Nun öffne ich Form2 mit einigen Daten, es werden dort also auch noch ein paar Datensätze in das DataSet für diese Instanz geladen. Nun bin ich schon bei 28mb.
Das wäre jetzt weiter noch nicht so tragisch, aber dieser Speicher scheint nicht wieder freigegeben zu werden, wenn ich alles bis auf das Form1 schließe. Gut, mir ist klar, dass wohl die Daten im ProjektDataSet erhalten bleiben und ich somit auf ca. 17mb verbrauch kommen müsste statt auf die 9mb wie beim Start, aber ich bleibe bei den 28mb.
Ich habe es auch schon versucht, im form_closed-Event, ein dataset.dispose() und sogar mal ein projektdataset.dispose() zu machen, aber auch das ändert gar nichts.
Irgendwie muss ich den Speicher doch auch wieder freigeben können. Ich habe jetzt nicht ewig lange das ganze laufen lassen, aber so nach und nach kommen ein paar kb beim Speicherverbrauch dazu. Wenn man nun über mehrere Stunden mit dem Programm arbeitet dürfte es dann mit Sicherheit zu Problemen kommen.
Was könnte ich denn da machen?
|
|
maro158
      
Beiträge: 35
|
Verfasst: Do 17.04.08 21:12
In der gemanagten Welt von .NET kümmert sich der Garbage Collector darum. Speicherzuweisungen sind unter .NET sehr billig und effektiv. Um die Performanz der Applikation zu erhalten, wird der Speicher nur dann freigegeben, wenn Ressourcenknappheit herrscht.
Was der Task-Manager anzeigt ist wirklich "cum grano salis" zu goutieren. Mich würden die 28 MB nicht weiter besorgen.
Es gibt einiges, dass Du tun könntest:
- selten benutzte Libraries on-demand laden, z.B. in ein separates, entladbares AppDomain
- entladbare Plug-ins verwenden
- statt in der Memory zu cachen, könntest Du dafür die Festplatte heranziehen
- wenn Deine Klassen nicht-gemanagte Ressourcen verwenden, die auch richtig freigeben
- die Lebensdauer Deiner Objekte möglichst kurz halten (viele kleine, statt wenig große Objekte erzeugen)
All das zu implementieren ist nicht trivial und wenn Du den Krieg gewonnen hast, kannst Du sehr leicht wider da stehen, wo Du angefangen hast, nur mit einer anderen Fragestellung: Wie verbessere ich die Performanz meiner Applikation?
|
|
lightsaver 
      
Beiträge: 24
C# (VS 2008 Prof.)
|
Verfasst: Do 17.04.08 21:46
Na das ist doch schonmal eine Antwort, wenn auch nicht unbedingt die, die ich bevorzugt habe
Ich finde es schade, dass man scheinbar nicht so einfach mal selbst dem GC sagen kann, dass er etwas entsorgen kann.
Ich habe aber jetzt nochmal getestet, gleich mal etwa 35 Instanzen von Form2 zu öffnen (und somit mal alle Daten, die derzeit in der DB vorhanden sind) zum bearbeiten bereitstellen, was beim Arbeiten später wohl nicht der Fall sein wird, und ich bin nicht so stark im Speicherverbrauch gestiegen. Beim Schließen wurden dann auch gleich noch ein paar mb freigegeben.
Ich denke also, dass ich mich so gut wie möglich an deine Tips halten werde und dann eigentlich nur hoffen kann, dass es kein Memoryleak gibt.
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Fr 18.04.08 08:09
lightsaver hat folgendes geschrieben: | | Ich finde es schade, dass man scheinbar nicht so einfach mal selbst dem GC sagen kann, dass er etwas entsorgen kann. |
Kann man, aber es lohnt sich wirklich nicht, sich darüber Gedanken zu machen. Beachte vor allem folgenden Hinweis, der ist für die Praxis entscheidend:
maro158 hat folgendes geschrieben: | | - die Lebensdauer Deiner Objekte möglichst kurz halten (viele kleine, statt wenig große Objekte erzeugen) |
Und Objekte, die IDisposable kennen, möglichst in using-Blöcke verpacken.
Wenn Du das berücksichtigst, erleichterst Du dem GC die Arbeit und kannst Dich selbst um wichtigere Aufgaben kümmern. Jürgen
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Di 22.04.08 16:23
Wenn du es genau wissen willst kannst du die Aktivität des GC mit den entsprechenden Performance Countern verfolgen.
Prinzipiell gilt aber: der GC verwaltet den Speicher in Segmenten (standardmäßig à 16MB), sobald ein Segment voll ist reserviert er sich ein neues. Sollte zu einem späteren Zeitpunkt dieses nicht mehr benötigt werden (weil eben alle Objekte Garbage sind) wird es jedoch nicht freigegeben sondern bleibt reserviert - er könnte es schließlich später wieder brauchen.
Bei 28MB ist dieses Verhalten auch vollkommen ok! Speicher der zwar reserviert aber im Moment nicht belegt ist wird erst dann freigegeben wenn das System oder die App dem GC signalisieren, dass sie größere Mengen freien Speicher brauchen - Stickwort "MemoryPressure". In deinem Fall würde ich aber Abstand davon nehmen!
Gruß, Motzi
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
|