Il conteggio dei riferimenti non è praticamente mai sufficiente per gestire la memoria a causa dei cicli. Se una lingua ha una mutazione, possiamo essenzialmente creare una struttura come
-------------------
| | |
| Head | Tail |
| | |
-------------------
| | |
| +-------+
|
1 <+
Ho messo troppa energia in questo pessimo schema
Ora che la testa è puntata verso la coda, il contatore dell'oggetto non scenderà mai a 0, il che significa che giacciono per sempre. Questo è un problema persistente per Perl ed è la ragione delle contorsioni con weak_prt
in C ++.
Inoltre francamente un buon GC è di ordini di grandezza più veloce del conteggio dei riferimenti. Bumping questi contatori costantemente (in particolare quando è necessario garantire la sicurezza dei thread) in realtà non è libero. Le cose intelligenti con la garbage collection generazionale / parallela possono dare un codice ad alte prestazioni praticamente in pausa!
È naturale chiedersi perché non potremmo iniziare con malloc e gratis in Lisp e vedere dove ci porta. In una lingua con chiusure, tuttavia, l'uso della gestione manuale della memoria è una battaglia pericolosa e costante. Sei costantemente in grave pericolo di chiudere qualcosa con una vita leggermente diversa e avere le cose lentamente a forma di pera. Questa complessità è evidente in C ++ con le nozioni a grana fine di catturare e muoversi dentro e fuori le chiusure, anche questo distrugge la serie di trucchi di tempo in Lisp per la simulazione di oggetti e altre creature utili.
TLDR: la raccolta dei dati inutili è in realtà piuttosto veloce e il conteggio dei riferimenti è semplicemente troppo ingenuo.