TL; DR: Eine Server-GC-fähige Anwendung zeigt dutzende von speziellen GC-Threads und hängt Überstunden. Was kann das erklären?
Ich stehe heutzutage an einem seltsamen Multi-Threading / Contention-Problem, das bei einem .NET-Dienst auftritt. Die Symptome sind folgende:
Ich habe sofort ein Problem in unserem Code vermutet, das dazu geführt hätte, dass der verwaltete Threadpool im Laufe der Zeit eine große Anzahl von Threads gestartet hat, die alle versuchen, eine oder mehrere gemeinsame Ressourcen zu teilen. Es schien, dass wir eine sehr kleine und sehr kontrollierte Verwendung des ThreadPools hatten.
Ich habe es geschafft, eine Dump-Datei eines noch nicht hängenden Dienstes zu erhalten, der bereits eine sehr hohe Anzahl von Threads hatte (mehr als 100, wenn es in einem normalen Zustand etwa 20 sein sollte)
Mit windbg + sos haben wir festgestellt, dass die ThreadPool-Größe in Ordnung war:
%Vor%Nur 8 Worker-Threads ... Dann habe ich alle verwalteten Thread-Stacks aufgelistet und viele gefunden, die ich nicht erkennen konnte. Siehe unten für ein Beispiel:
%Vor% Mit !threads -special
command fand ich schließlich, dass diese Threads spezielle GC-Threads waren:
Mehr als 60 "GC" -Threads ... Also überprüfte ich die Einstellungen meiner verschiedenen Dienstinstanzen und fand heraus, dass die problematischen mit GC Server
konfiguriert wurden, während die anderen nicht.
Weitere Informationen:
Was ich jetzt versuche zu tun:
GC Server
für die problematischen Instanzen zu deaktivieren, aber das Problem kann einige Zeit dauern. Hier sind meine Fragen :
Bei Server-GC gibt es einen Thread pro logischem Kern (das heißt Affinitätssatz für diesen Kern). In deinem Fall sollte es mindestens 32 Threads geben. Wenn Sie den Hintergrund-GC aktiviert haben, könnten weitere Worker-Threads das Diagramm für jeden Heap verarbeiten (reference ).
Beachten Sie auch, dass diese GC-Threads bei THREAD_PRIORITY_HIGHEST
ausgeführt werden, wodurch alle Threads, die vom GC noch nicht pausiert wurden, problemlos ausgehungert werden können ( Referenz ).
Nun, was Ihre anderen Threads anbelangt, wird 500+ in einem Prozess trotz des Garbage Collectors viele Konflikte erzeugen. Für Ihre Untersuchungen ist es wichtig, herauszufinden, was diese Threads sind.
Dinge, die Sie sich ansehen sollten
Sie können auch procdump.exe verwenden, um Minidumps zu erfassen, wenn die Leistung abnimmt.
Ich hatte ähnliche Probleme auf einem NUMA-Server. Dinge, die mir geholfen haben:
Tags und Links .net multithreading garbage-collection clr windbg