Entwickler-Ecke
Multimedia / Grafik - DirectShow IMediaControl (WebCam Stream) Memory Leak
Sven Bauermann - Di 29.11.11 10:01
Titel: DirectShow IMediaControl (WebCam Stream) Memory Leak
ujr - Di 29.11.11 10:16
Sven Bauermann hat folgendes geschrieben : |
Ich habe ein Memory Leak Problem mit einer WebCam Klasse und finde es nicht. |
Dafür gibt's Memory Profiler.
Sven Bauermann hat folgendes geschrieben : |
Ich poste hier die vollständige Klasse WebCamControl: |
Und gleich zwei Mal. Unleserlich. "Da - sucht mir den Fehler" - oder wie stellst Du Dir das vor?
Sven Bauermann - Di 29.11.11 10:40
Das Doppelposting ist bedauerlich, der Server hat ein Timeout gemeldet und den Misserfolg der Einstellung verkündet. Ich neige dazu solche Meldungen ernst zu nehmen.
Wie gesagt, keinerlei Absicht und eine Löschfunktion gibt es nicht für den Author.
Ich poste für die Übersicht nochmal isoliert die Funktion:
bei mediaCtrl.Run(),
Wird der Speicher belegt. In CloseInterface() sollte er wieder freigegben werden.
Ich habe damit schon einige Stunden zugebracht und erbitte lediglich Ratschläge, Ideen u.ä.,
es ist sehr selten das ich Hilfe dieser Art erbitten muss und mache dies auch nur wenn ich auf den üblichen Wegen nicht mehr weiterkomme.
Es gibt auch durchaus noch mehr Probleme dieser Art von anderen Entwicklern. Leider kaum Lösungen.
Es gab einen Poster auf Codeproject der eine Lösung hatte und das auch temporär ins Netz stellte.
Ist leider nicht mehr zu bekommen. Ich denk aber das es durchaus noch mehr Interessierte gibt und es lohnenswert wäre, für die Allgemeinheit den korrekten Weg zu veröffentlichen
Vielen Dank
Sven
Es passiert hier:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| private bool StartupVideo(UCOMIMoniker mon, Size _size) { int hr; try { if (!CreateCaptureDevice(mon)) return false;
if (!GetInterfaces()) return false;
if (!SetupGraph(_size)) return false;
if (!SetupVideoWindow()) return false;
hr = mediaCtrl.Run(); if (hr < 0) Marshal.ThrowExceptionForHR(hr);
return true; } catch (Exception ex) { throw new Exception(string.Format("{0}{1}",ex,ex.GetBaseException())); } } |
Moderiert von
Th69: C#-Tags hinzugefügt
ujr - Di 29.11.11 11:13
Hallo,
Sven Bauermann hat folgendes geschrieben : |
Ich poste für die Übersicht nochmal isoliert die Funktion: |
Mit "Unleserlich" meinte ich in erster Linie die fehlenden C#-Tags. Aber auch sonst - es ist einfach zu viel Code, vor allem auch viel unerhebliches. Wie z. B. die Funktion DisplayPropertyPage. Entweder deren Aufruf verursacht das Memory Leak, oder sie ist entbehrlich für die Fehlersuche. Diese Reduktion des Quelltexts ist Deine Aufgabe.
Sven Bauermann hat folgendes geschrieben : |
bei mediaCtrl.Run(),
Wird der Speicher belegt.
|
Wie kommst Du darauf?
Sven Bauermann hat folgendes geschrieben : |
erbitte lediglich Ratschläge, Ideen u.ä.,
|
Hast Du bekommen - was ist mit dem Memory Profiler?
Da gibt's nur Funktionsaufrufe - es wird kein Speicher belegt.
Generell sind doch offensichtlich z. B. die Get-Funktionen verdächtig, Speicher zu belegen. Also schaut man sich deren Dokumentation an. Nimm bspw.
IAMStreamConfig::GetStreamCaps [
http://msdn.microsoft.com/en-us/library/windows/desktop/dd319787(v=vs.85).aspx]. Da steht doch eindeutig, dass der Speicher hinter dem 2. Parameter frei gegeben werden muss, was bei Dir aber fehlt.
Sven Bauermann - Di 29.11.11 11:59
Danke Dir für die Hinweise.
Ich komme deshalb darauf, weil genau beim Aufruf dieser Zeile, der Speicher um die 11MB hochzählt.
Den Memory Profiler habe ich vorhin installiert. Ich versuche mich mit dem Programm einzuarbeiten.
Mit der IAMStreamConfig::GetStreamCaps hast Du sicher recht aber die wird nur mit der Funktion SetCaptureResolution(Size size) verwendet.
Das Programm ist auch ohne deren Aufruf verwendbar und das Problem ist das gleiche, leider.
Sven
Sven Bauermann - Di 29.11.11 12:18
Ich habe mir das mit Memory Profiler angesehen.
Eigentlich hatte ich erwartet, das im GDI+ Bereich irgendwas hängen bleibt.
Es passiert aber laut Übersicht in der ntdll.dll. Minimal im Heap, hauptsächlich im virtuellen Speicher.
:-(
Sven Bauermann - Di 29.11.11 17:50
Hallo ujr,
Du hattes recht. Ich habe an einer anderen Stelle 3 MB Memory Leak gefunden und freigeben und weitere 8 MB kommen wirklich von
hr = videoConfig.GetStreamCaps(i, out mt, pSC);
Allerdings bekomme ich die einfach mit C# Mitteln nicht freigegenen.
Was mache ich falsch?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| pSC = IntPtr.Zero; Marshal.FreeHGlobal(pSC); mt = null; Marshal.ReleaseComObject(videoConfigObj); videoConfigObj = null; Marshal.ReleaseComObject(videoConfig); videoConfig = null; |
ujr - Di 29.11.11 21:31
Zum einen hast Du die Reihenfolge von Null-Setzen und Freigabe vertauscht. Zum anderen steht doch in der oben verlinkten Dokumentation was wie freizugeben ist. Zudem war GetStreamCaps nur ein Beispiel - eben das erste, das mir auffiel.
Sven Bauermann hat folgendes geschrieben : |
Ich habe an einer anderen Stelle 3 MB Memory Leak gefunden und freigeben und weitere 8 MB kommen wirklich von
hr = videoConfig.GetStreamCaps(i, out mt, pSC); |
Nun ja, prinzipiell ist die Speicherverwaltung der CLR aufgrund der GC nicht sooo deterministisch. Insofern sind die Angaben des Memory Profilers tatsächlich wichtiger als Werte des Task Managers.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!