C# Speicherbedarf analysieren

-=Renegade=-

Lt. Junior Grade
Registriert
Nov. 2006
Beiträge
427
Hallo,


Ich hab seit kurzem ein Problem mit einer C# Anwendung. Eig. ist das Programm immer sehr zuverlässig gelaufen (ist relativ klein und simpel) aber seit einiger Zeit gibt es Probleme mit dem Speicher, mind. 1 mal täglich geht der Speicher von 16MB (Startbedarf) auf über 1GB und das innerhalb von ca. 1 Stunde (die Anwendung läuft dauernd)

Die letzte Änderung, seit der das Problem ungefähr auftritt, war eigentlich nur das wechseln auf eine neue Datenbank, was die Anwendung nur insofern betroffen hat, als das der Pfad zur DB geändert wurde.

Nun würde ich gerne das Problem analysieren unter welchen Umständen und wann das Problem genau auftritt. Welche Möglichkeiten habe ich dafür und wie kann ich das Problem am effektivsten beheben? (Garbage Collector manuell aufrufen?)


Vielen Dank im Voraus,

so long
Renegade
 
GC manuell wäre auch meine Idee gewesen. Machst nen Timer und lässt den ab und an laufen. Übertreibe es nur nicht, der GC braucht auch Leistung.
 
Die Frage ist nur, behebt man damit das Problem oder kaschiert man es nur (eben auf Kosten der Leistung)
Also macht es daher Sinn, das Problem vorher zu analysieren oder läuft die Behebung eines Speicherproblems sowieso immer auf den Garbage Collector hinaus (ein periodisches GC.collect() sollte reichen nehm ich an?)
 
Hast du einen Profiler im Visual Studio drin? Die Express Versionen haben leider keinen, vom MSDNAA die Ultimates haben einen. Geh mal damit zurande, damit du erstmal weißt, in welcher Funktion sich der Teufel versteckt.
 
Yuuri hat vollkommen recht. Besorg dir einen Profiler. Alles andere endet in raten. Es gibt zu viele Gründe, wieso dein Programm plötzlich so viel Speicher veranschlagt.

GC manuell aufzurufen kann man machen, wenn man weiß was man tut, andernfalls sollte man es lassen. Was man aber definitiv nicht tun sollte, unter gar keinen Umständen, ist GC periodisch zu forcieren. Es wird dein Problem sowieso nicht lösen. Stattdessen wirst du mit Performance-Einbrüchen bestraft.

Wenn sich an deinem Code wirklich nichts geändert hat, lediglich die DB, solltest du auch in Betracht ziehen, dass der DB-Connector ein Leak hat.
 
Hab offensichtlich leider keinen Profiler (Visual Studio 2010 Professional - hab in den Menüpunkten jetzt nichts passendes gefunden, dürfte es auch nur ab Premium aufwärts geben)

Gibt es vergleichbare kostenlose Profiler Plug-Ins oder ist es sinnvoller die Premium Variante zu installieren (hab dafür ne CD gefunden)

Desweiteren, inwiefern sind die Performance Einbrüche bemerkbar (also wie stark?)
Die Anwendung ist ansich nicht kritisch und es dauert mind. 1h, bis ein problematischer Wert erreicht wird, ich hab beispielsweise jetzt schon einen Timer alle 15 Minuten laufen, wenn ich den Collector da dazuhänge, sollte es nicht so drastisch werden? Ich versuche jetzt mehr Aufwand / Nutzen abzuschätzen, da ich mit Profiling bisher noch keine Erfahrung habe.
 
Jetbrains dotTrace oder RedGates ANTS Memory Profiler sind zwei ziemlich brauchbare Profiler.
Falls du bereits ReSharper benutzt, bietet sich dotTrace dank der nahtlosen Integration an.
Beide sind in der Test-Version uneingeschränkt nutzbar.

Bezüglich der Performance-Einbrüche. Es gibt leider keine Faustregel. Es hängt von deiner Applikation ab.
Hier ist ein Blog-Eintrag, der veranschaulicht, wann ein manueller Collect Sinn machen könnte - Link.
Das "Problem" mit GC ist, dass er in der Regel besser weiß, wann ein Collect sinnvoll ist und wann nicht. Wie in dem Blog beschrieben, gibt es aber durchaus die Möglichkeit, dass er irrt.

Hier noch ein paar Infos über den GC in .NET - Link. Unter Garbage Collection and Performance werden ein paar Szenarien/Probleme beschrieben und Lösungsansätze geliefert.

Wie auch immer. Eine Frage hätte ich noch. Du verwendest eine Oracle DB, richtig? Benutzt du zufällig ein low-level Framework alla LINQ2Oracle oder ähnliches (nicht ODAC)?
 
Zuletzt bearbeitet:
Danke für die Links, werd ich mir mal ansehen.

holy schrieb:
Wie auch immer. Eine Frage hätte ich noch. Du verwendest eine Oracle DB, richtig? Benutzt du zufällig ein low-level Framework alla LINQ2Oracle oder ähnliches (nicht ODAC)?

Gut kombiniert, ist aber ne andere Baustelle ;) Aber ja, ist auch in diesem Fall eine Oracle DB dahinter, benutze kein Framework sondern direkt über System.Data.OracleClient

Es werden in der Applikation aber eig. nur Stored Procedures aufgerufen, d.h. die Datenbank Logik liegt auch auf der Datenbank. Erst wenn alle clientseitigen Informationen "gesammelt" und validiert sind wird die Procedure auf der Datenbank aufgerufen und dort verarbeitet und danach das Ergebnis an die Applikation zurückgeliefert.

€: Welcher Profiler ist eig. besser dokumentiert bzw. eignet sich besser für Einsteiger? Oder sind alle gleich "kompliziert" ;)

€2: Hab mir jetzt mal den ANTS angeschaut, aber der dürfte wohl nur lokal bei mir Profilen können, hab ein wenig durchgetestet aber da gabs wie zu erwarten auch keine Probleme. Aber hab gerade gesehen, der jetBrains kann das auch Remote, oder hab ich das beim ANTS nur übersehen?
 
Zuletzt bearbeitet:
-=Renegade=- schrieb:
€: Welcher Profiler ist eig. besser dokumentiert bzw. eignet sich besser für Einsteiger? Oder sind alle gleich "kompliziert" ;)

Mehr oder weniger gleich kompliziert ;)

-=Renegade=- schrieb:
€2: Hab mir jetzt mal den ANTS angeschaut, aber der dürfte wohl nur lokal bei mir Profilen können, hab ein wenig durchgetestet aber da gabs wie zu erwarten auch keine Probleme. Aber hab gerade gesehen, der jetBrains kann das auch Remote, oder hab ich das beim ANTS nur übersehen?

Ich benutze dotTrace, von daher keine Ahnung. Aber laut Hersteller-Seite gibt es bei ANTS die Option "Attach to process". Damit sollte es auch remote funktionieren.
 
Zurück
Oben