Lebenszyklus
Lebenszyklus eines Objektes beschreibt die Reihenfolge der Prozesse
- Erzeugung durch Konstruktion
- Freigabe von Ressourcen am Ende des Einsatzes eines Objekts in einem Programm mittels
Dispose
- dem Ablauf der Speicherfreigabe am Lebensende, genannt Destruktion durch den GC
Werte vs. Referenztypen GC vs. Blockscope
.NET unterscheidet zwei grundsätzlich Arten der Speicherverwaltung:
- Verwaltung von Wertetypen im Stack. Die Speicherplatzfreigabe erfolgt automatisch am Blockende. Selbstdefinierte Destruktoren sind nicht möglich.
- Verwaltung von Referenztypen im Heap. Hier erfolgt eine automatische Speicherplatzbereinigung mittels des GC Dienstes. Vor der Speicherfreigabe kann ein Destruktor vom Objekt aufgerufen werden durch den GC.
Dynamische Typen
Wurden geschaffen, um den Zugriff auf Objekte aus untypisierter Sprachen wie JavaScript und Phyton zu vereinfachen. Die Existenz von Eigenschaften und Methoden wird erst zur Laufzeit überprüft. (Siehe Deserialisierung mittels NewtonSoft.JsonConverter.Deserialize, und Basic.Test._04_Objektorientiert._04_08_dynamische_TypenTests)
Verwaltete und unverwaltete Ressourcen
Die Ressourcen werden klassifiziert in
- verwaltete Ressource
-
ist ein Objekt, das mittels c#
new
Operator im verwalteten Heap angelegt wurde. - unverwaltete Ressource
- ist ein Objekt, das z.B. in einer C/C++ dll erzeugt wurde, und auf das über einen Zeiger verwiesen wird
Verwaltete Ressourcen werden automatisch vom GC aus dem Speicher entfernt. Um ihre Freigabe muss man sich in der Regel keine Gedanken machen.
Unverwaltete Ressourcen stehen nicht unter Kontrolle der CLR. Werden diese von
einem C#- Objekt erzeugt, dann muss sich dieses um die Freigabe an seinem Lebensende kümmern !
Beispiele:
- Verbindungsobjekt aus dem SQL-Server Datenbankprovider
- In einem DataReader gekapselter Datenbankcursor
- Grafikkontext der GDI+
Einheitliche Implementierung von Dispose mittels IDisposable
Die einheitliche Implementierung der Dispose Methode wird durch die
IDispose
Schnittstelle gewährleistet.
using
- Block
Mittels
using Block
kann der Aufruf von Dispose an einen Blockscope gebunden werden
Strategie der Ressourcenfreigabe
Eine optimale Ressourcenfreigabe ist gekennzeichnet durch:
- Ihre Durchführung wird garantiert
- Sie erfolgt zum frühest möglichen Zeitraum
Dies kann durch folgende Vorgehensweise erreicht werden:
- Implementiere die Ressourcenfreigabe in
Dispose
, um sie möglichts früh zu ermöglichen - Implementiere die Ressourcenfreigabe zusätztlich im Destruktor, um sie zu garantieren
Dispose
die Finalisierung
mittels GC.SupressFinalize
abzuschalten