Das Speichermanagement ist ein entscheidender Aspekt beim Arbeiten mit Objekten in Visual Basic, insbesondere wenn die Anwendung Ressourcen verwendet, die manuell freigegeben werden müssen: Dateien, Datenbankverbindungen oder externe Objekte.
In klassischem VB (VB6) wurden Ressourcen manuell durch den Aufruf von Set obj = Nothing freigegeben. In .NET (VB.NET) gibt es einen automatischen Garbage Collector, der nicht verwendete Objekte bereinigt. Allerdings erfolgt nicht jede Speicherfreigabe automatisch, insbesondere für unmanaged Ressourcen.
Der automatische Garbage Collector gibt Speicher für .NET-Objekte frei, weiß jedoch nicht, wie er externe oder manuelle Ressourcen rechtzeitig abholen kann (Dateideskriptoren, Verbindungen, Streams). Wenn man diese Details vernachlässigt, führt das zu Speicherlecks und Ressourcenblockierungen.
Für die korrekte Freigabe externer Ressourcen sollte das Interface IDisposable und der Ausdruck Using...End Using verwendet werden, was eine deterministische Freigabe garantiert.
Beispielcode:
' Garantierte Freigabe des Dateideskriptors Using reader As New StreamReader("data.txt") Dim content As String = reader.ReadToEnd() ' ... Datenverarbeitung ... End Using ' Für Objekte, die IDisposable nicht unterstützen, manuelle Freigabe: Dim obj As SomeComObject = New SomeComObject() ' ... Verwendung ... System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing
Wichtige Merkmale:
Wenn Using für FileStream nicht verwendet wird, wird die Ressource trotzdem dank GC freigegeben?
Nein, die Freigabe erfolgt zu einem unbestimmten Zeitpunkt. Es kann zu einer Datei-Lockierung und Ressourcenlecks kommen.
Ist der Aufruf von Set obj = Nothing gleichbedeutend mit der Aufruf von Dispose()?
Nein, Set obj = Nothing entfernt lediglich die Referenz, garantiert jedoch nicht die sofortige Freigabe von Ressourcen. Dispose() oder Using sind der einzig richtige Weg für deterministische Freigabe.
Muss Dispose für Objekte aufgerufen werden, die von DataSet/DataTable erben?
Ja, obwohl sie vom GC freigegeben werden, erfordern viele zugehörige Ressourcen (z. B. Datenbankverbindungen) einen manuellen Aufruf von Dispose oder Using, insbesondere für DataAdapter, Connection, Command.
Das Lesen von Daten aus einer großen Datei ohne Using, ohne Dispose. Nach einiger Zeit kann die Anwendung keine neue Datei öffnen: "Datei wird von einem anderen Prozess verwendet".
Vorteile:
Nachteile:
Öffnen einer Verbindung zur Datenbank oder einer Datei über Using. Holen, Verarbeiten von Daten, automatische Freigabe der Ressource.
Vorteile:
Nachteile: