La gestione della memoria è un aspetto cruciale nel lavoro con gli oggetti in Visual Basic, specialmente se l'applicazione utilizza risorse che richiedono un rilascio manuale: file, connessioni a database o oggetti esterni.
In VB classico (VB6) le risorse venivano liberate manualmente chiamando Set obj = Nothing. In .NET (VB.NET) è implementato un garbage collector automatico che pulisce gli oggetti non utilizzati. Tuttavia, non tutto il rilascio di memoria avviene automaticamente, specialmente per le risorse unmanaged.
Il garbage collector automatico libera la memoria dagli oggetti .NET, ma non sa come recuperare le risorse esterne o manuali in tempo (file descriptors, connessioni, stream). Ignorare questi dettagli porta a perdite di memoria e blocchi delle risorse.
Per un corretto rilascio delle risorse esterne, si utilizza l'interfaccia IDisposable e l'espressione Using...End Using, che garantisce un rilascio deterministico.
Esempio di codice:
' Rilascio garantito del file descriptor Using reader As New StreamReader("data.txt") Dim content As String = reader.ReadToEnd() ' ... elaborazione dei dati ... End Using ' Per oggetti che non supportano IDisposable, rilascio manuale: Dim obj As SomeComObject = New SomeComObject() ' ... utilizzo ... System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing
Caratteristiche chiave:
Se non si utilizza Using per FileStream, la risorsa verrà comunque liberata grazie al GC?
No, il rilascio avverrà in un momento indefinito. Potrebbe verificarsi un blocco del file e perdite di risorse.
La chiamata Set obj = Nothing è equivalente alla chiamata Dispose()?
No, Set obj = Nothing rimuove solo il riferimento, ma non garantisce il rilascio immediato delle risorse. Dispose() o Using è l'unico modo corretto per un rilascio deterministico.
È necessario chiamare Dispose per oggetti che ereditano da DataSet/DataTable?
Sì, anche se vengono liberati dal GC, molte risorse collegate (come le connessioni al DB) richiedono una chiamata manuale a Dispose o Using, specialmente per DataAdapter, Connection, Command.
Lettura di dati da un grande file senza Using, senza Dispose. Dopo un po' l'applicazione non riesce ad aprire un nuovo file: "File is in use by another process".
Vantaggi:
Svantaggi:
Apertura di una connessione a un database o file tramite Using. Ottenimento, elaborazione dei dati, liberazione automatica della risorsa.
Vantaggi:
Svantaggi: