Autor Beitrag
mats74
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 189
Erhaltene Danke: 26

Win 10
VS 2017/19, C++, C#
BeitragVerfasst: Di 06.08.13 09:13 
Hallo zusammen

In meiner Hauptanwendung habe ich ein modulares Form, welches beim User sehr oft geöffent und wieder geschlossen wird (bis zu 50'000 mal pro Tag).
Warum das so ist, ist eine andere Geschichte.
Im Arbeitsspeicher bleiben bei jedem Schliessen dieses Forms "Reststücke" zurück, die durch den GC nicht gelöscht werden.

Folgende Methoden habe ich bereits ausgeführt, aber ohne Erfolg:
ausblenden C#-Quelltext
1:
2:
3:
4:
// Dialog beenden
this.Close();
this.Dispose();
System.GC.Collect();

Dadurch wird der Arbeitsspeicher vollgerammelt und irgendeinmal gibt das Hauptprogramm den Geist auf.

Hat jemand eine Idee, wie ich den Arbeitsspeicher wieder freibekomme und das modulare Form entgültig vom Arbeitsspeicher lösche?

_________________
Gruss
mats74
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 06.08.13 09:29 
Wenn ein normales freigeben der Form nicht reicht wird deine Form noch von irgendwo referenziert. Nur nicht mehr referenzierte Objekte könenn wirklich richtig freigegeben werden.

Zitat:
Dadurch wird der Arbeitsspeicher vollgerammelt und irgendeinmal gibt das Hauptprogramm den Geist auf.


Mit welchen Fehler bei welcher Operation? Es macht einen Unterschied ob wirklich der Speicher voll ist oder ob irgendeine Resource verbraucht ist (WindowsHandles etc.). Eine OutOfMemoryException steht in .Net leider nicht zwingend für das was man bei dem Namen vermuten würden.
mats74 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 189
Erhaltene Danke: 26

Win 10
VS 2017/19, C++, C#
BeitragVerfasst: Di 06.08.13 09:43 
Zitat:
... Nur nicht mehr referenzierte Objekte könenn wirklich richtig freigegeben werden...


Folgender Aufrug der Form habe ich:
ausblenden C#-Quelltext
1:
2:
Form2 _form2 = new Form2(this)
_form2.ShowDialog();

Das Form wird folgendermassen geschlossen:
ausblenden C#-Quelltext
1:
this.Close();					

Durch das Schliessen der Form mit der Methode Close() sollte die Referenzierung aufgehoben sein, oder verstehe ich das falsch?
Wie kann ich eine Aufhebung der Refernzierung erzwingen?

_________________
Gruss
mats74
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 06.08.13 10:06 
Bei einem ShowDialog bietet sich immer an ein using zu benutzen. Da hast du die maximale Sicherheit das das Ding auch aufgeräumt wird.

ausblenden C#-Quelltext
1:
2:
3:
4:
using (Form2 form = new Form2(this))
{
    form.ShowDialog();
}


Zitat:
Wie kann ich eine Aufhebung der Refernzierung erzwingen?


Nur indem du alle Referenzen auf die Form aufhebst. Bei deinem Code fällt z.B auf das du this an den Constructor der Form übergibst. Da hast du also irgendwas selbst gebastelt. Wenn du in diesem Constructor irgendwas gebastelt hast wodurch this dann dauerhaft einen Verweis auf die Form2 hat wird Form2 nicht mehr vollständig freigegeben egal wie oft du Close, Dispose GC.Collect aufrufst. Erst müssen alle Alle Verweise auf die Form2 Instanz müssen weg.

Für diesen Beitrag haben gedankt: mats74
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4803
Erhaltene Danke: 1060

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 06.08.13 10:23 
Hallo mats74,

hast du Eventhandler bei dem Dialog registriert? Denn solange kann das Form-Objekt nicht vom GC aufgeräumt werden.
s. z.B.
Event Handling and Garbage Collection in .NET
Weak Events in C#
C#: Advanced Event Handling: Memory Optimization, Thread-safety, and Proper Disposal

Für diesen Beitrag haben gedankt: mats74
mats74 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 189
Erhaltene Danke: 26

Win 10
VS 2017/19, C++, C#
BeitragVerfasst: Di 06.08.13 15:22 
Zitat:
Bei einem ShowDialog bietet sich immer an ein using zu benutzen. Da hast du die maximale Sicherheit das das Ding auch aufgeräumt wird.

Vielen Dank euch beiden.
Ich habe mir eure Vorschläge zu Herzen genommen und getestet.
So auf die Schnelle bin ich mit der Using-Anweisung zu sehr guten Resultaten gekommen (habe ich zu vor noch nie verwendet).
Der Arbeitsspeicher verhält sich im normalen Bereich auch bei grösseren Forms (bis zu ca. 2'500 Steuerelementen getestet).
Leider habe ich bei nicht modalen Formaufrufen schwierigkeiten den GC beim aufräumen auf die richtige Fährte zu lotzen .

Ich muss die Codestruktur mit den Aufrufen der Dialoge im Moment so stehen lassen, da der Quellcode sehr gross ist und ich die Grafik von der Logik nicht in geforderter Frist ablösen kann.

Gibt es für die nicht modularen Forms eine ähnliche Methode gemäss der using-Anweisung?
Wäre mir im Moment sehr geholfen.

_________________
Gruss
mats74
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4803
Erhaltene Danke: 1060

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 06.08.13 18:06 
Bei nicht-modalen Forms gibt es kein Patentrezept in der Art, sondern man muß selber alle möglichen Referenzen verwalten und entsprechend freigeben.
Hast du denn schon mal einen "Memory Profiler" dafür benutzt?
mats74 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 189
Erhaltene Danke: 26

Win 10
VS 2017/19, C++, C#
BeitragVerfasst: Mi 07.08.13 08:00 
Bin gerade dabei.
Der liefert mir auch die entsprechenden (misserablen) Werte :shock: .

Es bleibt mir aber im Moment keine ander Möglichkeit, als die (zu)vielen Aufrufe mit modalen Forms zu gestalten und entsprechend zu handeln.
Danach werde ich die Codesturktur zur Brust nehmen und entsprechend strukturieren, damit dieses "Gebastel" ein Ende hat :wink: .
Danke für den Hinweis.

_________________
Gruss
mats74