220 likes | 468 Views
Garbage Collection unter .NET. Garbage Collection Optimierung Finalization Resurrection. Vorteile von Garbage Collection. Kein explizites Freigeben von Speicher Beseitigung möglicher Fehlerquellen Keine Fragmentierung des Heaps Performance-Vorteil
E N D
Garbage Collection unter .NET Garbage Collection Optimierung Finalization Resurrection
Vorteile von Garbage Collection • Kein explizites Freigeben von Speicher • Beseitigung möglicher Fehlerquellen • Keine Fragmentierung des Heaps • Performance-Vorteil • Garantierte „locality of reference“ bei Erzeugung • Durch Verdichtung des Heaps rücken langlebige Objekte zusammen
Mark & Compact • Markieren aller erreichbaren Objekte, Entfernen aller nicht markierten
Mark & Compact • Verdichtung des Heaps, Neuberechnung der Zeiger (auch members)
Optimierung durch Generationen • Für die meisten Applikationen gilt: • Je neuer ein Objekt, desto kürzer die Lebenszeit, und je älter, desto länger wird die Lebenszeit sein • Neuere Objekte haben stärkere Beziehungen untereinander und werden öfter verwendet • Und: Teile des Heaps zu bearbeiten ist effizienter als den gesamten zu verdichten • Optimierung durch differenzierte Behandlung von Objekten unterschiedlichen Alters
Generationen • Neue Objekte sind „Generation 0“ • Objekte, die einen GC-Lauf überleben, erreichen die nächsthöhere Generation
Generationen: Performance • GC kann Freigabe auf Generation 0 beschränken • Da neuere Objekte meist kurze Lebensdauer haben, wird in Gen. 0 meist mehr Speicher freigegeben als in den anderen • Beschränkung der Mark-Traversierung • Innere Referenzen werden nur verfolgt bei • neuen Objekten • alten Objekte, auf die seit der letzen Collection geschrieben wurde
Multi-Threading • Wenn GC eine Collection starten will, müssen alle Threads angehalten werden • Mechanismen • Fully interruptible code • Safe Points (vom JITC in Code eingefügt) • Für unmanaged code • „Hijacking“ um Thread anzuhalten • Thread kann während Collection weiterlaufen • „pinned objects“ erforderlich
Finalization • Ressourcen müssen freigegeben werden • GC vergibt Speicher, gibt ihn wieder frei • aber nicht möglich für unbekannte Ressourcen • Netzwerkverbindungen • Dateihandles • Datenbanken, etc. • Objekt kann durch Finalization Ressourcen freigeben, wenn es durch GC entfernt wird
Finalization – Code Beispiel Public class NetworkObj { NetworkResource res; Public NetworkObj() { res = new NetworkResource(); } ... ~NetworkObj() { res.close(); } }
Finalization: Behandlung • Enthält ein Objekt eine Finalize-Methode, wird ein Zeiger auf das Objekt in die Finalization Queue gestellt (bei Erzeugung des Objekts)
Finalization: Behandlung • Wird ein Objekt als Garbage betrachtet, und befindet sich ein Zeiger darauf im Fin.-Queue, wird dieser in den „F-reachable Queue“ kopiert
Finalization: Behandlung • Objekte im F-reachable Queue können noch NICHT freigegeben werden, da erst ihre Finalize-Methode aufgerufen werden muß
Finalization: Behandlung • Separater Thread wird gestartet, der die Objekte im F-reachable Queue abarbeitet • Objekte können erst im nächsten GC-Lauf tatsächlich freigegeben werden!
Finalization Nachteile • Erzeugung von Objekten mit Finalize-Methode dauert länger • Freigabe dauert länger (Aufrufe der Methoden erforderlich) • Speicher wird nicht sofort freigegeben • Ist kein (deterministischer) Destruktor • Darf nicht direkt aufgerufen werden • Zeitpunkt und Reihenfolge der Ausführung sind willkürlich • Nur verwenden wenn wirklich nötig
Dispose • Die meisten Ressourcen wollen möglichst früh wieder freigegeben werden • Unteilbare Ressourcen (z.B. Datei) können durch die Nicht-Vorhersagbarkeit des Freigabe-Zeitpunktes problematisch sein • Lösung: • (manuell aufrufbare) Freigabe-Methode • Finalize als Backup
Dispose • In der Dispose-Methode kann durchSystem.GC.SuppressFinalize(this);der Zeiger aus dem Finalization Queue entfernt werden, Finalize wird nicht aufgerufen • Vorteile: • Wird explizit Dispose() aufgerufen (Normalfall), wird das Freigeben effizienter • Wird vergessen, gibt der GC die Ressourcen frei
Resurrection • F-reachable Queue Zeiger werden als Wurzelzeiger aufgefaßt • D.h. das Objekt ist tot, wird in den Queue verschoben und lebt wieder bis zur nächsten Collection (der Zeiger ist dann entfernt) • Objekt kann in Finalize eine globale oder statische Referenz auf sich selbst erzeugen • wird „resurrected“, da wieder erreichbar • Allerdings wird Finalize das nächste Mal nicht mehr ausgeführt
Resurrection • Nutzen von Resurrection • z.B. für Objekt-Pool • hilfreich für Objekte mit zeitintensiven Konstruktoren (z.B. Datenbankverbindung) • Im Normalfall nicht verwenden, da schwer zu durchschauen
WeakReference • Direkte Referenzen sind „strong references“ • „weak references“ für Objekte, die man später zwar wieder braucht, die das System aber bei Bedarf freigeben darf sr = new SomeObject(); WeakReference wr = new WeakReference(sr); sr = null; ... sr = (SomeObject)wr.Target; if (sr==null) sr = new SomeObject();
Direkte Interaktion mit dem GC System.GC.Collect(); System.GC.Collect(int generation); System.GC.GetGeneration(object); System.GC.GetTotalMemory(); System.GC.KeepAlive(object); System.GC.SuppressFinalize(object); System.GC.ReRegisterForFinalize(object); System.GC.WaitForPendingFinalizers();
Literatur • http://msdn.microsoft.com/library/default.asp?url=/msdnmag/issues/1100/GCI/TOC.ASP • http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/default.aspx • Kevin Burton: .NET Common Language Runtime Unleashed, Sams Publishing 2002 • Dave Stutz, Ted Neward, Geoff Shilling: Shared Source CLI Essentials. O'Reilly 2003