Werden statische Elemente jemals vom Garbage Collector gesammelt?Müllsammlung von statischen Elementen
Antwort
Objekte, die von statischen Variablen referenziert werden, werden nur Garbage Collected gesammelt, wenn die relevante AppDomain
Garbage Collected ist. In Client-Anwendungen gibt es oft nur eine einzige AppDomain
, die für die Dauer des Prozesses lebt. (Eine Ausnahme ist, wenn die Anwendung ein Plug-in-Architektur verwendet -. Unterschiedliche Plug-ins in verschiedenen AppDomain
s geladen werden kann, und die AppDomain
kann später entladen werden)
In ASP.NET "AppDomain
recycling" geschieht periodisch (aus verschiedenen Gründen) - wenn dies der Fall ist, und die statischen Variablen innerhalb dieser AppDomain
nicht mehr als GC-Roots fungieren, und somit nicht verhindern, dass Objekte Müll gesammelt werden.
Wenn Sie befürchten, dass ein Objekt als Müll gesammelt wird, während Sie noch über eine statische Variable darauf verweisen, können Sie sich entspannen. Während Sie auf das Objekt zugreifen können, wird kein Müll gesammelt.
Mitglieder werden nicht gesammelt ... Objekte sind.
Also, wenn Sie die Ref. Wenn Sie static member auf null setzen, wird jedes Objekt, auf das es zuvor gezeigt hat, gesammelt. Wenn nicht, wird es hängen bleiben, bis die AppDomain ausfällt (Jede AppDomain hat ihre eigenen statischen Sachen)
Ein statisches Element zu einem Referenztyp ist eine Referenz, die auf eine Instanz zeigen kann oder nicht. Wenn es auf eine Instanz verweist, wird diese Instanz erst gesammelt, wenn das statische Element entladen ist. Wenn der Typ in eine bestimmte AppDomain geladen wird, kann diese entladen werden. Ansonsten passiert es nur, wenn die Anwendung beendet wird.
Die kurze Antwort ... Nein; Alle aktuellen Implementierungen des .NET-Garbage Collectors sammeln keine Objekte, auf die von statischen Klassenmemberfeldern stark verwiesen wird, bis die Anwendungsdomäne, der die statischen Klassenelementelemente, auf die starke Referenzen verweisen, abgerissen wird.
Die längere Antwort ... Potenziell ja; Der Garbage Collector basiert seine Entscheidung, ein Objekt bei der Erreichbarkeit des Objekts zu sammeln, nicht auf Referenzen (stark oder schwach) auf das Objekt. Wenn der Garbage Collector theoretisch feststellen könnte, dass kein Code jemals wieder ein bestimmtes Objekt von einem bestimmten Punkt an benötigen würde (das heißt, das Objekt ist von keinem Codepfad aus erreichbar), könnte der GC sogar dieses Objekt erfassen wenn es noch stark von statischen Klassenmitgliedsfeldern referenziert würde. Dies ist absolut zulässig, da Sie dies nie bemerken würden, da kein Code jemals versuchen würde, auf das Feld für statische Klassenmitglieder zuzugreifen, das den Verweis auf das Objekt enthält. Du magst fragen, warum interessiert es mich dann, wenn ich nie wieder über eine der starken Referenzen auf das Objekt zugreifen werde? Der Grund, den Sie interessieren würden, ist Nebenwirkungen. Sie könnten beispielsweise annehmen, dass Sie einem statischen Klassenelementfeld einen Verweis auf ein SafeHandle-Objekt zuweisen, das eine nicht verwaltete Ressource darstellt, dass das SafeHandle-Objekt niemals geschlossen wird und somit das nicht verwaltete "Objekt", das es darstellt, am Leben erhält. Dies gilt nur für die aktuellen Implementierungen des GC. Eine zukünftige Implementierung des GC könnte Objekte sammeln, auf die durch statische Klassenmitgliedsfelder stark Bezug genommen wird, wenn diese Objekte durch irgendeinen der übrigen Programmcodes nicht mehr erreichbar sind.
Schafft dies nicht eine große Ineffizienz? Ich erstelle oft private statische Hilfsmethoden. Oder alle Erweiterungsmethoden. Ich frage mich, wie viel Speicher diese verbrauchen? Wenn ich eine Hilfsmethode für ein Objekt habe, ist es besser, den Helfer einfach als Instanz zu belassen, damit er gesammelt wird? –
@ P.Brian.Mackey: Wenn Sie statische Methoden haben, welchen Speicher stellen Sie sich vor, verbraucht zu werden? Wenn Sie statische * Variablen * haben, haben Sie einen globalen Status, was oft eine schlechte Idee ist. Aber die Methoden selbst sind eine andere Sache. –
Mein Fehler. Ich nahm an, dass Methoden auf dem Stack/Heap wie Variablen erstellt werden. Anscheinend ist das nicht der Fall. –