Condividi tramite


Metodi Finalize e distruttori

Per la maggior parte degli oggetti creati dalla propria applicazione, si può contare sul supporto di Garbage Collector di .NET Framework, che svolge in modo implicito tutte le necessarie attività di gestione della memoria. Se però si creano oggetti che incapsulano risorse non gestite, sarà necessario rilasciare esplicitamente queste ultime quando si smette di utilizzarle. Il tipo più comune di risorsa non gestita è un oggetto che incapsula una risorsa del sistema operativo, quale un file, una finestra o una connessione di rete. Sebbene Garbage Collector sia in grado di tenere traccia del ciclo di vita di un oggetto che incapsula una risorsa non gestita, esso non ha una specifica conoscenza di come pulire la risorsa. Per tali tipi di oggetti, .NET Framework fornisce il metodo Object.Finalize, che consente a un oggetto di pulire correttamente le risorse non gestite quando la memoria da esso utilizzata viene reclamata dal Garbage Collector. In base all'impostazione predefinita, il metodo Finalize non effettua alcuna operazione. Se si desidera che Garbage Collector esegua operazioni di pulizia sull'oggetto prima di reclamarne la memoria, è necessario eseguire l'override del metodo Finalize nella propria classe.

NotaNota

Per implementare il metodo Finalize in C#, è necessario utilizzare la sintassi del distruttore.Nella versione 2.0 di .NET Framework Visual C++ fornisce una sintassi specifica per l'implementazione del metodo Finalize, come descritto in Destructors and Finalizers in Visual C++.Nelle versioni 1.0 e 1.1 di .NET Framework Visual C++ utilizzava la sintassi del distruttore per il metodo Finalize, analogamente a C#.

Garbage Collector tiene traccia degli oggetti che dispongono di un metodo Finalize utilizzando una struttura interna denominata coda di finalizzazione. Ogni volta che la propria applicazione crea un oggetto che ha un metodo Finalize, Garbage Collector crea una voce nella coda di finalizzazione che punta all'oggetto. La coda di finalizzazione contiene voci per tutti gli oggetti presenti nell'heap gestito il cui codice di finalizzazione deve essere chiamato prima che Garbage Collector possa reclamarne la memoria.

NotaNota

Nell'esempio di codice fornito per il metodo GC.KeepAlive viene illustrato come una procedura di Garbage Collection troppo incisiva possa determinare l'esecuzione di un finalizzatore mentre un membro dell'oggetto recuperato è ancora in esecuzione e come utilizzare il metodo KeepAlive per evitare questa situazione.

Un metodo Finalize non deve generare eccezioni, perché queste non possono essere gestite dall'applicazione e possono provocarne l'interruzione.

L'implementazione dei metodi Finalize o dei distruttori può avere un impatto negativo sulle prestazioni ed è pertanto consigliabile evitarne l'uso non motivato. Per reclamare la memoria utilizzata da oggetti dotati di metodi Finalize, occorrono almeno due procedure di Garbage Collection. Quando Garbage Collector effettua una procedura di collection, reclama la memoria occupata da oggetti inaccessibili privi di finalizzatori. In questa fase, non può effettuare la raccolta degli oggetti inaccessibili dotati di finalizzatori. Rimuove invece le voci di tali oggetti dalla coda di finalizzazione e le pone in un elenco di oggetti contrassegnati come pronti per la finalizzazione. Le voci di tale elenco puntano a quegli oggetti presenti nell'heap gestito che sono pronti ad accettare la chiamata del proprio codice di finalizzazione. Mediante il Garbage Collector vengono chiamati i metodi Finalize degli oggetti inclusi nell'elenco e vengono quindi rimosse le voci dall'elenco. Una procedura di Garbage Collection successiva rileverà che gli oggetti finalizzati sono realmente inutilizzati perché non sono più puntati da alcuna delle voci comprese nell'elenco degli oggetti contrassegnati come pronti per la finalizzazione. In tale procedura di Garbage Collection, la memoria degli oggetti viene effettivamente reclamata.

Vedere anche

Riferimenti

Finalize

Concetti

Override del metodo Finalize

Sintassi del distruttore in C# e C++