2016-04-11 6 views
5

Ich arbeite an einem Programm, das interaktive Diagramme erstellt. Das folgende Problem tritt jedoch auf, selbst wenn der Rendering-Layer des Programms deaktiviert ist.C#, Warum läuft der GC mehrmals pro Sekunde?

Auf bestimmten Bildschirmen in meiner Anwendung, nach den Visual Studio 2015 Diagnostic Tools, läuft der GC etwa 4 Mal pro Sekunde zurück und tötet die Leistung meiner Anwendung (von 120fps auf so niedrig wie 15fps).

Ich habe einige Speicher-Snapshots mit unerwarteten Zuordnungen erwartet, aber nach den Snapshots gibt es nur ein oder zwei Zuordnungen und Sammlungen von System.Internal.HandleCollector + HandleType alle paar Sekunden, was normal erscheint, auch wenn das Problem tritt nicht auf.

Einige andere Dinge, die ich bemerkt habe:

  • Diese auf mehreren Rechnern geschieht.
  • Dies geschieht mit oder ohne den Debugger angeschlossen.
  • Die meiste CPU-Zeit der Anwendung befindet sich in clr.dll.
  • Der Grund für jeden GC-Lauf wird als "Small object heap Zuweisung" aufgeführt, auch wenn keine beobachtbaren Zuordnungen in den Snapshots vorhanden sind.

An diesem Punkt bin ich ratlos. Hat jemand das gesehen oder weiß, wo ich mit dem Debuggen anfangen sollte?

+0

Was verwenden Sie zum Generieren der Graphen? GDI +? Aktualisieren Sie die Grafik bei Datenänderungen oder ständig? –

+0

Wir verwenden DirectX, über SharpDX. Die Graphen werden einmal erzeugt, basierend auf Benutzereingaben modifiziert und für jeden Frame gezeichnet. Das Problem tritt jedoch weiterhin auf, selbst wenn der Rendering-Layer vollständig entfernt wurde. –

+0

Ich bin mir nicht sicher, wie die Frage "Wie debugge ich den GC, der wegen Zuordnungen ausgeführt wird, wenn Visual Studio keine Zuordnungen anzeigt?" hat keine "klare Problemaussage" und ist "für andere Leser nicht nützlich". –

Antwort

0

Sie sollten den Code überprüfen, wo Sie den GC anrufen. Normalerweise läuft es weit weniger als 4 Mal pro Sekunde. Fügen Sie einen Debugger oder Profiler an eine Instanz an, bei der das Problem auftritt, wo der GC aufgerufen wird. Vielleicht ist es in einer Drittanbieter-Bibliothek. Oder ein Code, an den du nicht gedacht hast.

+0

Mit dem eingebauten Profiler habe ich festgestellt, dass es der GC ist. Der GC wird nie aus dem Code aufgerufen. Die einzige Third-Party-Bibliothek, die wir verwenden, dient zum Rendern, und das Problem tritt auch auf, wenn das Rendering deaktiviert ist. –

2

Versuchen Sie, Ihre app.config mit, dies zu ändern und ein Lauf

<configuration> 
    <runtime> 
     <gcServer enabled="true"/> 
    </runtime> 
</configuration> 

Weitere interessante Details machen über GC hier https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx

+0

Da das Problem ist, dass der GC läuft und nicht die Leistung des GC, während er läuft, würde dies nicht nur das Problem verdecken? –

+0

Diese Einstellung ändert die Art und Weise, wie und wann Threads gestoppt wurden, während der GC arbeitet. Dieser spezielle Konfigurationseintrag besagt, dass die Speicherbereinigung verzögert wird. Sie haben also viel Speicher und erwarten, dass Ihre App nur den Speicher verwendet. Speicherzuweisung ist schnell in .Net. Nicht verwendete Speichersammlung ist langsam. Wenn Sie genug Speicher haben, um Ihren Bericht zu erstellen, wird GC auf einen guten Moment warten. Versuchen Sie es und sehen Sie, ob es die Leistung verbessert. –

2

Von https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx

Garbage Collection ist tritt auf, wenn eine der die folgenden Bedingungen sind erfüllt:

Das System h als geringer physischer Speicher.

Der Speicher, der von zugeordneten Objekten auf dem verwalteten Heap verwendet wird, überschreitet einen akzeptablen Schwellenwert. Dieser Schwellenwert wird während der Ausführung des Prozesses kontinuierlich angepasst.

Die GC.Collect-Methode wird aufgerufen. In fast allen Fällen müssen Sie diese Methode nicht aufrufen, da der Garbage Collector kontinuierlich ausgeführt wird. Diese Methode wird hauptsächlich für einmalige Situationen und Tests verwendet.

Vielleicht erfüllen Sie eine der drei oben aufgeführten Bedingungen. Es scheint, dass Ihre Anwendung viel Speicher verwendet und daher Garbage Collection ausgeführt wird, um zu versuchen, einige Objekte zu bereinigen, um Speicherplatz freizugeben.

Es könnte auch möglich sein, dass GC.Collect() irgendwo in Ihrem Code ist und der Garbage Collector erneut ausgeführt wird.

Here sind einige Richtlinien zur Fehlerbehebung bei der Garbage Collection. Ein Abschnitt scheint sich speziell auf das Problem zu beziehen, das Sie haben. Unter dem Abschnitt, der als "Problem: CPU-Auslastung während einer Garbage Collection ist zu hoch" gekennzeichnet ist, heißt es:

CPU-Auslastung wird während einer Garbage Collection hoch sein. Wenn in einer Garbage Collection ein erheblicher Teil der Prozesszeit verbracht wird, ist die Anzahl der Collections zu häufig oder die Sammlung dauert zu lange. Eine erhöhte Zuordnungsrate von Objekten auf dem verwalteten Heap führt dazu, dass die Garbage Collection häufiger auftritt. Das Verringern der Zuordnungsrate verringert die Häufigkeit von Speicherbereinigungen.

Sie können die Zuweisungsraten mithilfe des Leistungszählers "Zugeordnete Bytes/Sekunde" überwachen. Weitere Informationen finden Sie unter Leistungsindikatoren in .NET Framework.

Die Dauer einer Sammlung ist in erster Linie ein Faktor der Anzahl der Objekte, die nach der Zuordnung überleben. Wenn viele Objekte gesammelt werden müssen, muss der Garbage Collector eine große Menge an Speicher durchlaufen. Die Arbeit, die Überlebenden zu verdichten, ist zeitaufwendig. Um festzustellen, wie viele Objekte während einer Auflistung behandelt wurden, legen Sie im Debugger am Ende einer Garbage Collection für eine bestimmte Generation einen Haltepunkt fest.

+0

Laut GC.GetTotalMemory() werden 10 MB Speicher verwendet, während das Problem auftritt. GC.Collect() wird nie manuell aufgerufen. Und es gibt mehr als genug physische Speicher. –

+0

Sie hätten nicht zufällig GC.Collect irgendwo in Ihrem Code, oder? Ich halte das auch in meiner Antwort fest. – Tophandour

+0

Es ist bereits in Ihrer Antwort, es ist Bedingung # 3. –

Verwandte Themen