Ich hatte einige Probleme mit einem WCF-Webdienst (einige Speicherauszüge, Speicherlecks usw.) und ich führe ein Profiling-Tool (ANTS Memory Profiles).Speicher aus C# -Wörterbuch in einem statischen Objekt freigeben
Nur um herauszufinden, dass sogar mit der Verarbeitung über (ich führe einen bestimmten Test und dann gestoppt), Generation 2 ist 25% des Speichers für den Web-Service. Ich habe diesen Speicher aufgespürt, um festzustellen, dass ich ein Wörterbuchobjekt mit (-1, null) Elementen mit -1 Hashcode hatte.
Der Workflow des Web-Service bedeutet, dass während der Verarbeitung bestimmte Elemente hinzugefügt und dann aus dem Wörterbuch entfernt werden (einfach Add
und Remove
). Keine große Sache. Aber nachdem alle Elemente entfernt wurden, scheint das Wörterbuch voll von (null, null) KeyValuePair
s zu sein. Tausende von ihnen in der Tat, so dass sie einen großen Teil des Speichers belegen und schließlich einen Überlauf auftritt, mit der entsprechenden erzwungenen Anwendung Pool Recycling und DW20.exe erhalten alle CPU-Zyklen, die es bekommen kann.
Das Wörterbuch ist in der Tat Dictionary<SomeKeyType, IEnumerable<KeyValuePair<SomeOtherKeyType, SomeCustomType>>>
(System.OutOfMemoryException because of Large Dictionary), also habe ich bereits überprüft, ob es eine Art von Bezug hält Dinge.
Das Wörterbuch ist in einem statischen Objekt enthalten (um es für verschiedene Verarbeitungsthreads durch Verarbeitung zugänglich zu machen) also von dieser Frage und vielem mehr (Do static members ever get garbage collected?) Ich verstehe, warum dieses Wörterbuch in Generation 2 ist. Aber das ist auch die Ursache von denen (null, null)? Auch wenn ich Gegenstände aus dem Wörterbuch entferne, ist immer etwas im Speicher belegt?
Es ist kein Geschwindigkeitsproblem wie in dieser Frage Deallocate memory from large data structures in C#. Es scheint, dass Speicher nie zurückgewonnen wird.
Gibt es etwas, was ich tun kann, um tatsächlich Elemente aus dem Wörterbuch zu entfernen, nicht einfach nur mit (Null, Null) Paaren zu füllen? Gibt es noch etwas, das ich überprüfen muss?
+ !: Für die richtige Forschung und eine gute Frage zu schreiben. – Virtlink
'List <>' hat eine 'TrimExcess()' Methode, 'Dictionary <,>' leider nicht. Dachte, das war ein einfaches Ergebnis :) –
Macht das Aufrufen von Dictionary.Clear() einen Unterschied? – Alex