Modifica: riscritto per meglio esprimere il mio punto di vista.
1: Relazioni entità
Ho incontrato questo problema con le entità. Supponiamo che abbiano due classi, autore e articolo. Inoltre ho un render (Autore) e render (articolo) che restituiscono documenti html che descrivono entrambi gli elementi. L'autore avrà un elenco di articoli e l'articolo avrà informazioni sull'autore.
L'autore e l'articolo avranno un ciclo di riferimento. Possiamo tentare di risolvere questo ciclo introducendo un riferimento debole. Cosa succede se il riferimento è dall'autore all'articolo? Quindi il rendering (articolo) non manterrà i riferimenti all'Autore in vita e quindi l'oggetto verrà deallocato prima di essere utilizzato per ottenere il nome dell'autore. Ma, se il riferimento è da Articolo a Autore che funziona bene, ma render (Autore) non registrerà alcun riferimento contro Articolo e saranno deallocati prima che i loro titoli possano essere recuperati.
L'introduzione di riferimenti deboli risolve il problema fintanto che tutte le relazioni hanno una direzione definita in cui la direzione opposta è chiaramente secondaria. Ma alcune relazioni non funzionano in questo modo.
D'altra parte: Questo problema preciso deriva solo nei casi in cui abbiamo associazioni tra oggetti. Questo è ogni oggetto ha bisogno di tenere un riferimento reciproco all'altro. Forse la lingua potrebbe supportare tali associazioni in modo naturale e quindi dare loro un trattamento speciale con il conteggio dei riferimenti. Potrebbe essere fatto funzionare.
2: Strutture dati
Le strutture dati hanno spesso cicli di riferimento. L'esempio più comune è una lista doppiamente collegata. Inoltre, non è raro che la struttura ad albero abbia puntatori prossimi / precedenti nelle foglie per una rapida iterazione.
D'altra parte: sospetto che la maggior parte di questi cicli siano effettivamente interrotti dal funzionamento della struttura dati. Ad esempio, quando un oggetto viene rimosso da un elenco collegato, i due riferimenti al nodo verranno ripristinati eliminando così i riferimenti.
3: eliminazioni deterministiche
Una ragione per usare il conteggio dei riferimenti è che si ottengono cancellazioni deterministiche. Gli oggetti saranno cancellati in tempi prevedibili. Ciò significa che puoi fare cose come chiudere file, rilasciare blocchi, ecc. Perché sai che gli oggetti verranno eliminati in modo tempestivo.
Il problema è che questo tende a rompersi. Se accidentalmente creo un ciclo i miei file non vengono chiusi e le mie serrature non vengono rilasciate. Inoltre, non ricevo errori come risultato di ciò.
Questo non è davvero un problema con il conteggio dei riferimenti. È un caso in cui il vantaggio (eliminazioni deterministiche) non funziona davvero lasciandomi con meno motivi per volere il conteggio dei riferimenti.
D'altra parte: si potrebbe sostenere che il vero problema è che non abbiamo effettuato test automatici per garantire che gli oggetti siano stati distrutti. Se avessi una cosa del genere saremmo informati quando questo non ha funzionato.
4: velocità
Un altro motivo per cui il conteggio dei riferimenti è perché è più veloce. Tuttavia, sembra che questo non sia effettivamente vero. Tutti gli incrementi e decrementi sono in realtà piuttosto costosi. (Diventa molto brutto quando si inizia a considerare il threading.) Quindi non è chiaro che qui si ottenga un vantaggio in termini di velocità. In effetti, potrebbe essere più veloce usare un'altra tecnica GC.
5: Convenience
Se si lavora in un linguaggio di conteggio dei riferimenti, devo preoccuparmi di non creare cicli di riferimento. Mi sono trovato a creare cicli su base regolare. Nella maggior parte dei casi ho potuto risolvere questo problema introducendo un riferimento debole. Ma perché preoccuparsi? Sembra che ci siano alcuni vantaggi nel contare i conteggi, ma non sembra che si siano verificati (Vedi 3 & 4) Di conseguenza, non sembra valsa la pena di combattere i cicli.
In conclusione
Il conteggio dei riferimenti semplicemente non sembra fornire abbastanza benefici rispetto alle tipiche implementazioni dei GC per compensare il mal di testa in più che fornisce ai programmatori.