Jochens Weblog

ESCde Developer Blog

  Home :: Kontakt :: RSS Feed
  12 Posts :: 0 Artikel :: 4 Kommentare :: 0 Trackbacks

Archiv

Post Kategorien

ESCde

ESCde Blogger

Mittwoch, 25. April 2007 #

Das grundlegende Konzept der Referenz unter .NET sollte jedem klar sein: Eine Referenz identifiziert ein Objekt, ohne gleichzeitig die exakte Speicheradresse des Objektes zu bezeichnen. Solange der Entwickler eine Referenz auf ein Objekt hat, ist gewährleistet, dass dieses nicht vom Garbage Collector "zerstört" wird. Sobald der Entwickler die letzte Referenz eines Objektes auf "null" setzt, ist das Objekt unereichbar und darf vom Garbage Collector abgebaut werden. Diese Referenzen nennt man auch "starke Referenzen" ("strong reference").

Im Unterschied hierzu gibt es allerdings auch "schwache" Referenzen ("weak references"). Bei diesen hat der Entwickler noch eine Referenz auf sein Objekt, allerdings kann der Garbage Collector das Objekt trotzdem zerstören. Zunächst hört sich dieses Konzept völlig sinnfrei an, allerdings gibt es Situationen, in denen schwache Referenzen sehr hilfreich sein können: Stellen Sie sich vor, Sie schreiben eine Anwendung, die aus zwei relativ unabhängigen Bereichen besteht. Zunächst arbeitet der Anwender in Bereich A, wo sich sehr viele, große Objekte ansammeln, beispielsweise eine Liste aller Dateien des Rechners. Nun wechselt der Anwender in Bereich B. Ob er wieder in Teil A zurückkehrt, ist ungewiss. Falls der Garbage Collector nun Speicher frei machen muss, sollte er also prinzipiell unsere Dateiliste aus Teil A löschen können. Wenn wir hierzu unsere Referenzen alle auf "null" setzen, ermöglichen wir dem Garbage Collector diese Option. kehrt der User allerdings in Bereich A zurück (und der GC musste zuvor nicht aktiv werden), würde unsere Liste im Speicher zwar noch existieren, allerdings müssten wir sie neu aufbauen, da wir keine Referenz mehr haben. Genau für solche Fälle sind die schwachen Referenzen.

Und nun wollen wir uns mal ansehen, wie man solch eine schwache Referenz einsetzt:

using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication5 { class Program { class BigChunk { } static void Main(string[] args) { // das große Objekt BigChunk bc = new BigChunk(); // schwache Referenz auf das Objekt erzeugen, starke Referenz freigeben System.WeakReference wr = new WeakReference(bc); bc = null; // starke Referenz aus schwacher wiederherstellen: BigChunk bc2 = (BigChunk) wr.Target; if (bc2 == null) { // der Garbage Collector war schneller... bc2 = new BigChunk(); } } } }

Das Erzeugen einer schwachen Referenz ist sehr einfach, man muss lediglich eine starke Referenz auf das betroffene Objekt als Konstruktionsparameter übergeben. Allerdings muss man aufpassen, dass man auch auf jeden Fall die starke Referenz (beziehungsweise alle vorhandenen) auf null setzt. Sonst ist das Objekt trotz der erzeugten schwachen Referenz für den Garbage Collector unerreichbar.

Möchte man später wieder mit dem Objekt arbeiten, weißt man einfach die Target-Eigenschaft der schwachen Referenz einer starken Referenz zu. Hierbei muss man allerdings auf den Cast achten! Anschließend muss man die starke Referenz noch auf null hin überprüfen. Zeigt die Referenz auf null, so hat der Garbage Collector das Objekt in der Zwischenzeit gelöscht und man muss es erneut erzeugen.

Abschließend bleibt noch zu sagen, dass man schwache Referenzen nur dann einsetzen sollte, wenn sich in den betroffenen Objekten keine Daten befinden, die man nicht selbst wiederherstellen kann. Schwache Referenzen bieten also einen Ansatz zur besseren Ausnutzung des Speichers und einer schöneren Zusammenarbeit mit dem Garbage Collector. Allerdings sollten sie immer wohlbedacht angewendet werden!