Gestione delle durate degli oggetti tramite il conteggio dei riferimenti

Nei sistemi a oggetti tradizionali, il ciclo di vita degli oggetti, ovvero i problemi relativi alla creazione e all'eliminazione di oggetti, viene gestito in modo implicito dal linguaggio (o dal linguaggio di runtime) o in modo esplicito dai programmatori dell'applicazione.

In un sistema in continua evoluzione, costruito in modo decentrato costituito da componenti riutilizzati, non è più vero che qualsiasi client, o anche qualsiasi programmatore, "sa" come gestire la durata di un componente. Per un client con i privilegi di sicurezza appropriati, è ancora relativamente semplice creare oggetti tramite una semplice richiesta, ma l'eliminazione di oggetti è un'altra questione completamente. Non è necessariamente chiaro quando un oggetto non è più necessario e deve essere eliminato. I lettori che hanno familiarità con gli ambienti di programmazione di Garbage Collection, ad esempio Java, potrebbero non essere d'accordo. Tuttavia, gli oggetti Java non si estendono sui limiti del computer o persino dei processi e pertanto la Garbage Collection è limitata agli oggetti che vivono all'interno di uno spazio a processo singolo. Java forza inoltre l'uso di un singolo linguaggio di programmazione. Anche quando il client originale viene eseguito con l'oggetto, non può semplicemente arrestare l'oggetto, perché altri client o client potrebbero avere ancora un riferimento.

Un modo per garantire che un oggetto non sia più necessario è dipendere interamente da un canale di comunicazione sottostante per informare il sistema quando tutte le connessioni a un oggetto tra processi o tra canali sono scomparse. Tuttavia, gli schemi che utilizzano questo metodo sono inaccettabili per diversi motivi. Un problema è che potrebbe richiedere una differenza importante tra il modello di programmazione cross-process/cross-network e il modello di programmazione a processo singolo. Nel modello di programmazione cross-process/cross-network, il sistema di comunicazione fornirà gli hook necessari per la gestione della durata degli oggetti, mentre nel modello di programmazione a processo singolo gli oggetti sono connessi direttamente senza alcun canale di comunicazione intermedio. Un altro problema è che questo schema potrebbe anche causare un livello di software fornito dal sistema che interferisce con le prestazioni dei componenti nel caso in-process. Inoltre, un meccanismo basato sul monitoraggio esplicito non tenderebbe a scalare verso molte migliaia o milioni di oggetti.

COM offre un approccio scalabile e distribuito a questo set di problemi. I client indicano a un oggetto quando lo usano e quando vengono eseguiti e gli oggetti vengono eliminati quando non sono più necessari. Questo approccio impone che tutti gli oggetti contano i riferimenti a se stessi. I linguaggi di programmazione come Java, che intrinsecamente dispongono di propri schemi di gestione della durata, ad esempio Garbage Collection, possono usare il conteggio dei riferimenti COM per implementare e usare internamente gli oggetti COM, consentendo al programmatore di evitare di usarli.

Proprio come un'applicazione deve liberare memoria allocata una volta che la memoria non è più in uso, un client di un oggetto è responsabile della liberazione dei relativi riferimenti all'oggetto quando tale oggetto non è più necessario. In un sistema orientato agli oggetti, il client può eseguire questa operazione solo assegnando all'oggetto un'istruzione per liberarsi.

È importante deallocare un oggetto quando non viene più usato. La difficoltà consiste nel determinare quando è appropriato deallocare un oggetto. Ciò è semplice con le variabili automatiche (quelle allocate nello stack): non possono essere usate all'esterno del blocco in cui sono dichiarate, quindi il compilatore li dealloca quando viene raggiunta la fine del blocco. Per gli oggetti COM, che vengono allocati dinamicamente, spetta ai client di un oggetto decidere quando non devono più usare l'oggetto, in particolare oggetti locali o remoti che potrebbero essere in uso da più client contemporaneamente. L'oggetto deve attendere il completamento di tutti i client prima di liberarsi. Poiché gli oggetti COM vengono modificati tramite puntatori di interfaccia e possono essere utilizzati da oggetti in processi diversi o in altri computer, il sistema non può tenere traccia dei client di un oggetto.

Il metodo COM per determinare quando è appropriato deallocare un oggetto è il conteggio dei riferimenti manuali. Ogni oggetto mantiene un conteggio dei riferimenti che tiene traccia del numero di client connessi, ovvero il numero di puntatori esistenti a qualsiasi interfaccia in qualsiasi client.

Per ulteriori informazioni, vedi gli argomenti seguenti:

Uso e implementazione di IUnknown