Frage

Ich habe Probleme mit einem langsamen Speicherleck in meinem gemischten Modus C ++ / CLR .NET-Anwendung.

(Es ist C ++ nativen statischen Bibliotheken verknüpfen in eine VS2008 C ++ / CLR Windows Forms-Anwendung mit der "/ clr" Compiler-Einstellung)

Typisches Verhalten: app beginnt mit 30 MB (private Speicher). Dann Speicher slowish leckt, sagt jede Stunde ein MB, wenn sie unter simulierter schwerer Last läuft. Dies simuliert die App Live für Tage oder Wochen sein.

Ich habe mehrere Tools versucht, mit Speicherlecks einschließlich aufzuspüren sowohl das CRT-Debugging-Material, das mit dem Visual Studio CRT Libs kommt. Ich habe auch ein kommerzielles Leckerkennungswerkzeug ( „Memory Validator“).

Beiden Bericht vernachlässigbar Speicherlecks beim Herunterfahren (ein paar kleinere Einträge, die Menge auf ein paar KB, die ich über nicht besorgt bin). Auch ich kann sehen, beim Laufen, dass der verfolgte Speicher scheint nicht viel zu, dass betragen (so glaube ich nicht, es nur Speicher ist, gehalten wird und nur bei ca. Ausfahrt freigegeben). Ich bekomme rund 5 MB Speicher aufgeführt (von gesamt> 30 MB).

Das Werkzeug (Memory Validator) ist Setup alle Speicherauslastung (einschließlich malloc, neue, virtuelle Speicherzuweisung und eine ganze Reihe von anderen Arten von Speicherzuweisung) zu verfolgen. Grundsätzlich hat jede Einstellung, für die Speicher-Spur ausgewählt worden ist.

Das .NET Bild berichtet, dass es rund 1,5 MB Speicher verwendet (von perfmon).

Hier ist eine letzte Bit Information: Wir haben eine Version der App, die als native Konsolenanwendung läuft (rein nativen - überhaupt nicht CLR). Das ist 95% der gleiche wie der im gemischten Modus außer ohne die UI-Sachen. Dies scheint nicht Speicher überhaupt zu lecken, und Spitzen bei etwa 5MB privaten Bytes.

Also im Grunde, was ich versuche über hier zu bekommen, ist, dass ich nicht glaube, jeder des nativen Codespeicher undicht ist.

Ein weiteres Stück des Puzzles: ich das gefunden, die im gemischten Modus Anwendungen auf Speicherlecks beziehen, wenn 2.0-Framework-Targeting (was ich bin): http://support.microsoft.com/kb/961870

Leider sind die Details infuriatingly spärlich so dass ich nicht sicher bin, ob es relevant ist. Ich habe versucht, mit 3,5 Rahmen anstelle von 2,0 Targeting, aber immer noch das gleiche Problem (vielleicht habe ich dieses Recht nicht tun).

Wer irgendwelche Vorschläge?

Ein paar Dinge, die mir helfen können:

  • Gibt es irgendeine andere Art von Speicherzuordnungen, die ich nicht verfolgt?
  • Wie kommen die Zahlen addieren sich nicht? Ich erhalte 5 MB CRT Speichernutzung, 1,5 MB .NET Speicher, so wie kommt die ganze App 30MB privaten Bytes verwendet? Ist das alles in dem .NET-Framework gebunden? Warum ich in dem Leck-Tool sehe diese nicht? Wird nicht das .NET Framework als eine Art zugewiesenen Speicher erscheinen?
  • Jede andere Lecksuche-Tools, die mit gemischten Modus Anwendungen gut funktionieren?

Vielen Dank für jede Hilfe

John

War es hilfreich?

Lösung

OK fand ich endlich das Problem.

Es wurde durch eine falsche Einstellung verursacht für / EH (Exception Handling).

Im Grunde genommen mit gemischten Modus NET-Anwendungen, müssen Sie sicher, dass alle statisch gelinkte Bibliotheken machen kompiliert mit / EHa anstelle des Standard / EHs.

(Die App selbst muss auch mit / EHa kompiliert werden, aber dies ist ein gegeben -.. Die Compiler Fehler melden, wenn Sie es nicht verwenden Das Problem ist, wenn Sie in anderen statischen nativen Bibliotheken verknüpfen)

Das Problem ist, dass Ausnahmen in der verwalteten Bit der App gefangen, die mit / EHs nicht die Ausnahme korrekte Abwicklung der am Ende zusammengestellt innerhalb nativen Bibliotheken geworfen wurden. Destruktoren für C ++ Objekte werden dann nicht richtig bezeichnet.

In meinem Fall dies geschah nur in einem seltenen Ort, also warum es mir Alter nahm zu erkennen.

Andere Tipps

Wie Spence sagte, aber für C ++ / CLI;) ....

Für jedes Objekt, das Sie in C ++ / CLI verwenden, wenn Sie das Objekt mehr erstellen die von Ihnen C ++ Code, sollten Sie versuchen, Stapel Zuordnung seymantics zu verwenden, auch wenn dies eine Compiler magische Art der Sache ist, ist es in der Lage Setup die verschachtelte __try {} {} __finally Anweisungen, die Sie von nativen Code zu verwenden verwendet werden können (dh sie Setup in einer Art und Weise einen Aufruf nicht zu verlieren zu entsorgen).

Nish des diesem Artikel auf Speicherprobleme , perticularly über Event Abonnenten, wenn Sie Ihre Objekte Veranstaltung zuweisen, werden Sie möglicherweise undicht ...

Als letztes Mittel (oder vielleicht zuerst :), eine Sache, die ich in der Vergangenheit getan haben, ist die Verwendung des CLR Profiler API machen, Constrained Execution Regionen , können sie arbeiten Wunder, aber auch leider schwer zu Nachrüstungs in nicht-rein-Code.

Diese jüngste MSDN Mag , Artikel Dokument ist eine Menge perfmon Typ-Speicher sperlunking (followup für diesen älteren ).

Von der VS Perf Blog , sie zeigen, wie SOS in Visual Studio zu verwenden, die sehr nützlich sein können, rouge auf der Spur DLL, sind verwandte Beiträge auch gut.

Maoni Stephen Blog und Rick Byers ist ein Entwickler mit dem CLR-Diagnose-Team, viele seinen Blog -buddies sind auchgute Quelle ist, aber ich stark auch auf die ganz neue dev / Diagnose Forum . Sie haben vor kurzem den Umfang ihrer Diskussionen erweitert.

Code Coverage-Tools und dieses Unternehmen , ist recht gut, es in der Lage ist abzuleiten nativen / verwalteten Lecks des von ihm Profilspuren ist, bringt Ihnen zurück zu den genauen Quellenleitungen (auch wenn optimierte, ganz nett (und es hat eine 30 Tage Testversion)))).

Viel Glück !! einige dieser Hoffnung hilft, es ist nur frisch in meinem Kopf, als ich viel von der gleichen Arbeit jetzt tue;)

ausprobieren: DebugDiags .
Nach einigen Speicher-Dumps zu erzeugen, wird es Ihnen einen schönen sommerlichen von dem, was Speicher zugewiesen wurde, und je nach HVE der Suche, kann es Ihnen sagen, von wem sie zugeordnet wurde.

Sie können ein Referenzleck haben, schauen Sie in ANTS Profilierungssoftware. Ants Profiler

Ein Referenzleck ist die .net Äquivalent eines Speicherleck, halten Sie Verweise auf ein Objekt, das hält er Müll gesammelt werden, und somit in Gebrauch Sie Speicher beginnt zu steigen.

Ist es möglich, Sie haben einige Entsorger verpasst, kann passieren, wenn Ihr mit GDI + und viele andere APIs.

Wenn Ihr laufen die statische Analyse-Tool FXCop hat es eine Regel zu überprüfen, ob Sie dispose genannt haben (oder die „Verwendung“ verwendet) Aussagen über Ihre Objekte, die die Schnittstelle zur Verfügung stellen. In .NET, wenn eine Funktion nicht verwalteten Code verwendet wird es in der Regel eine dispose oder schließt Methode für Sie nicht die Ressource / Speicher verlieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top