Garbage Collection unter NET Garbage Collection Optimierung Finalization
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 Network. Obj { Network. Resource res; Public Network. Obj() { res = new Network. Resource(); }. . . ~Network. Obj() { 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 durch System. GC. Suppress. Finalize(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
Weak. Reference § 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 Some. Object(); Weak. Reference wr = new Weak. Reference(sr); sr = null; . . . sr = (Some. Object)wr. Target; if (sr==null) sr = new Some. Object();
Direkte Interaktion mit dem GC System. GC. Collect(); System. GC. Collect(int generation); System. GC. Get. Generation(object); System. GC. Get. Total. Memory(); System. GC. Keep. Alive(object); System. GC. Suppress. Finalize(object); System. GC. Register. For. Finalize(object); System. GC. Wait. For. Pending. Finalizers();
Literatur - http: //msdn. microsoft. com/library/default. asp? url=/msdnmag/iss ues/1100/GCI/TOC. ASP http: //msdn. microsoft. com/msdnmag/issues/1200/GCI 2/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
- Slides: 22