Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Memory Leak bei mehr als 10.000 GDI Objekten finden
baer999
myCSharp.de - Member



Dabei seit:
Beiträge: 375

Themenstarter:

Memory Leak bei mehr als 10.000 GDI Objekten finden

beantworten | zitieren | melden

Hallo,
ich habe scheinbar ein Memory Leak Problem, zumindest hauen mir die GDI Objekte ab bis auf 10.000 und dann knallts!
Hat jemand einen guten Tipp für mich, wie ich das Memory Leak identifizieren kann (Problem ist es laufen mehrere Threads und GUI Elemente und es ist für mich im Moment quasi die Nadel im Heuhaufen...).

Thx!
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Hi baer999,

du mußt für GDI-Objekte (und alle anderen unverwalteten Objekte) die Dispose-Methode aufrufen, die den unverwalteten Speicher wieder freigibt.

Wenn du das schon machst, mußt du uns ein paar mehr Informationen über dein Programm geben.

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
baer999
myCSharp.de - Member



Dabei seit:
Beiträge: 375

Themenstarter:

beantworten | zitieren | melden

Die Befürchtung ist, dass es um Bitmap und Image Objekte gehen könnte.

Also Bsp. Quellcode hier:
https://documentation.devexpress.com/#WindowsForms/CustomDocument17565

Dort werden Image Objekte erzeugt und in Ribbon Items verwendet.

Reicht es dann das jeweilige Ribbon Items zu Disposen, wo das Image zugewiesen war oder muss ich jedes Image Objekt einzeln Disposen?


Im Speziellen geht es um ein UserControl, in dem Bitmap und Controls erzeugt werden.
Anfangs dachte ich, wenn ich das UserControl lösche würde schon alles darauf erzeugte auch mit aus dem Speicher geschmissen. Dann wachte ich nach und nach auf (dispose auf alle Controls und davor die Events deregistrieren), nun befürchte ich, dass ich jedes Image in eine separate Variable packen muss und diese dann auch alle Disposen muss, wenn das UserControl geschlossen wird.

Ist dem so?

Thx!
private Nachricht | Beiträge des Benutzers
Palin
myCSharp.de - Member



Dabei seit:
Beiträge: 1.090

beantworten | zitieren | melden

Zitat von MrSparkle
du mußt für GDI-Objekte (und alle anderen unverwalteten Objekte) die Dispose-Methode aufrufen, die den unverwalteten Speicher wieder freigibt.

Das macht im zweifel auch der GC, wenn keine Referenz mehr auf dem Objekten ist. Es ist aber trotzdem besser Dispose aufzurufen.

Meist ist das Problem, das noch eine Referenz auf den Objekten besteht. Beliebt sind hier Delegates (Events), da die Richtung der Referenz umgekehrt ist als man Vermutet. (Der Button hat z.B. durch sein Click Event eine Referenz auf die Form. Und das VM oder Model (MVVM-Pattern) oft durch PropertyChanged noch eine Reference auf die View (VM).

(Wenn ich das jetzt richtig im Kopf habe)Dann gibt es noch ein paar Objekte, die der GC auch nicht wegräumen darf auch weil wenn keine Reference auf sie besteht. Weil sie z.B. auf den Speicher "gepint" wurden. (Einer einen der Timer ist es glaube ich so).
Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Hi Palin,
Zitat von Palin
Das macht im zweifel auch der GC

Nein, eben nicht. Deswegen heißt unverwaltete Objekte "unverwaltet". Du mußt dich selbst darum kümmern, wenn nicht, bekommt du irgendwann eine GDI-Exception.

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Palin
myCSharp.de - Member



Dabei seit:
Beiträge: 1.090

beantworten | zitieren | melden

Also um da genauer zu werden der GC ruft natürlich nicht Dispose auf sondern den Finilazier, der wenn man es sauber Implementiert hat Dispose aufruft (Ist in der MSDN zu finden).

Man kann natürlich auch nicht Verwaltete Ressourcen benutzen, die Implementieren dann aber auch nicht die IDisposabel Schnittstelle.
Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Es geht nicht um die Implementierung der Schnittstelle, sondern um die korrekte Verwendung für unverwaltete Objekte. Deine Hinweise sind nicht wirklich hilfreich für die Beantwortung der eigentlichen Frage.

Man braucht da auch keine Vermutungen anstellen, es steht alles so in der Doku:

Cleaning Up Unmanaged Resources:
Zitat
However, when you create objects that include unmanaged resources, you must explicitly release those resources when you finish using them in your app. The most common types of unmanaged resource are objects that wrap operating system resources, such as files, windows, network connections, or database connections. Although the garbage collector is able to track the lifetime of an object that encapsulates an unmanaged resource, it doesn't know how to release and clean up the unmanaged resource.

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Palin
myCSharp.de - Member



Dabei seit:
Beiträge: 1.090

beantworten | zitieren | melden

Das man unverwaltete Objekte Ressourcen freigeben muss habe ich ja gesagt.

Aber Objekte bei denen du Dispose aufrufen kannst, sind nicht unverwaltet sondern Benutzen nur intern unverwaltete Ressourcen (z.B. Image Klasse).

Und wenn Objekte, die Dispose Implementieren vom GC nicht Freigegeben werden Liegt es nicht daran, das Dispose nicht aufgerufen werden sondern das noch eine Referenz auf sie gibt.
Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern
private Nachricht | Beiträge des Benutzers
wcseller
myCSharp.de - Member



Dabei seit:
Beiträge: 188

beantworten | zitieren | melden

Ich nutze zum Auffinden vom Memory-Leaks das hier:

http://memprofiler.com/

Gerade das Auffinden von Referenzen, die ein finalisieren der Objekte verhindern (wie von Palin beschrieben) IMHO sehr gut geeignet...
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16.030

beantworten | zitieren | melden

VS hat ab 2013 einen Profiler integriert.
Ich vermute aber wie Palin, dass es an einer vergessenen Referenz liegt oder am falsch implementierten Dispose.
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 2.033
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Währe um einiges hilfreicher wenn man mal Code sehen könnte.
Dann könnte man das Problem auch einfacher beurteilen.
Ansonsten können wir hier alle nur raten und kommen der Lösung nicht wirklich näher.
Ansätze bzw. mögliche Lösungen haben wir ja genug aber ohne konkreten Code können wir das raten sparen.

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers