3 Stimmen

Kann ich die Instanzen von lebenden Objekten eines bestimmten Typs in C# bekommen?

Dies ist eine C# 3.0 Frage. Kann ich Reflection oder Speicherverwaltungsklassen des .NET-Frameworks verwenden, um die Gesamtanzahl der lebenden Instanzen eines bestimmten Typs im Speicher zu zählen?

Ich kann dasselbe mit einem Speicherprofilierer machen, aber das erfordert zusätzliche Zeit zum Entleeren des Speichers und beinhaltet eine Software von Drittanbietern. Was ich möchte, ist nur die Überwachung eines bestimmten Typs und ich möchte eine leichte Methode, die sich leicht in Unit-Tests einfügen lässt. Der Zweck, die lebenden Instanzen zu zählen, besteht darin sicherzustellen, dass ich keine erwarteten lebenden Instanzen habe, die zu einem "Memory Leak" führen.

Danke.

1voto

STW Punkte 42452

Um es vollständig innerhalb der Anwendung durchzuführen, könnten Sie einen Instanzzähler verwenden, aber er müsste explizit in jedem einzelnen Klasse codiert und verwaltet werden - soweit ich weiß gibt es keine Lösung, die es ermöglicht, das Framework aus dem ausführenden Code abzufragen, um zu sehen, wie viele Instanzen leben.

Was Sie eigentlich suchen, gehört wirklich in den Bereich eines Profilers. Sie können einen kaufen oder Ihren eigenen erstellen, aber dazu muss Ihre Anwendung als Kindprozess des Profilers ausgeführt werden. Es ist übrigens keine einfache Aufgabe, Ihren eigenen zu entwickeln.

Wenn Sie den Instanzzähler in Betracht ziehen möchten, müsste es so etwas sein:

public class MyClass : IDisposable
    public MyClass()
    {
        ++ClassInstances;
    }

    public void Dispose()
    {
        --ClassInstances;
    }

    private static new object _ClassInstancesLock;
    private static int _ClassInstances;
    private static int ClassInstances
    {
        get
        {
            lock (_ClassInstancesLock)
            {
                return _ClassInstances
            }
        }
    }

Dies ist nur ein sehr grobes Beispiel, ohne Tests für die Kompilierung; 0%ige Garantie für Thread-Sicherheit (entscheidend für diese Art der Herangehensweise) und es lässt die Tür weit offen, dass Dispose aufgerufen wird, der Instanzzähler abnimmt, aber das Objekt nicht ordnungsgemäß vom GC entfernt wird. Um dieses Bündel von Freude zu diagnostizieren, benötigen Sie, wie Sie es vermutet haben, einen professionellen Profiler - oder zumindest windbg.

Bearbeiten: Ich habe gerade die allerletzte Zeile Ihrer Frage bemerkt und musste sagen, dass mein obiger Ansatz, so schlampig und fehleranfällig er auch sein mag, Sie fast garantiert über die wahre Anzahl von Instanzen täuschen wird, wenn Sie einen Leck erleben. Das beste Werkzeug, meiner Meinung nach, um diese Probleme anzugehen, ist ANTS Memory Profiler. Version 5 ist eine zweischneidige Sache, da sie Performance- und Memory-Profiler in zwei separate SKUs aufgeteilt haben (früher waren sie zusammengebunden) aber Memory Profiler 5.0 ist absolut blitzschnell. Das Profilieren dieser Probleme war früher langsam wie Melasse, aber sie haben es irgendwie umgangen.

Wenn es sich nicht um ein persönliches Projekt mit keiner Absicht zur Weiterverbreitung handelt, sollten Sie die wenigen Hundert Dollar investieren, die für ANTS erforderlich sind - aber natürlich zunächst die Testphase nutzen. Es ist ein großartiges Werkzeug für genau diese Art von Analyse.

0voto

Pavel Minaev Punkte 97251

Der einzige Weg, den ich sehe, um dies zu tun, ist ohne jede Form von Instrumentierung die CLR Profiling API zu verwenden, um die Lebensdauer von Objekten zu verfolgen. Mir sind keine APIs bekannt, die dem verwalteten Code zur Verfügung stehen, um dasselbe zu tun, und soweit ich weiß, behält CLR die Liste der aktiven Objekte nirgendwo bei (selbst mit dem Profiler-API müssen Sie die Datenstrukturen dafür selbst erstellen).

VB.NET verfügt über eine Funktion, mit der Sie Objekte im Debugger verfolgen können, aber es generiert tatsächlich zusätzlichen Code speziell für diesen Zweck (der im Grunde alle erstellten Objekte in der internen Liste schwacher Verweise registriert). Sie könnten das auch tun, indem Sie z.B. PostSharp verwenden, um Ihre Assemblys nachzubearbeiten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X