Perché per liberare memoria non appena il contatore di riferimento raggiunge lo zero, devi mantenere un contatore di riferimento. E questo non viene gratis. In genere, limita la velocità effettiva.
Di solito ci sono due strategie principali per implementare i garbage collector: traccianti e collezionisti di conteggio di riferimento. (Ce ne sono altri, ma quelli sono quelli in uso nella maggior parte dei sistemi di gestione della memoria automatica tradizionali.)
In genere, i GC di conteggio di riferimento tendono ad avere un throughput peggiore ma una latenza migliore (e più prevedibile) rispetto alla traccia dei collettori, mentre i collettori di tracciamento hanno un rendimento migliore ma una latenza più elevata e meno prevedibile. Un altro grosso problema con (almeno con semplici implementazioni) il conteggio dei riferimenti ai garbage collector è che non possono eseguire cicli di raccolta dati. In genere, è necessario eseguire un raccoglitore di traccia insieme ad un raccoglitore conteggio di riferimento (ad esempio, ad esempio, CPython).
In pratica, tutti i moderni sistemi di gestione della memoria automatica ad alte prestazioni di livello industriale (tutti i collector di Oracle JDK, Oracle JRockit e molti altri JVM, Microsoft CLR, Mono, la maggior parte delle implementazioni ECMAScript, tutte le implementazioni di Ruby, quasi tutti i Python implementazioni, tutte le implementazioni Smalltalk, tutte le implementazioni Lisp, ecc.) stanno raccogliendo i collezionisti, quindi c'è un po 'di loop di feedback auto-rinforzante qui: più soldi vengono messi in ricerca sul tracciamento dei GC perché sono popolari e diventano più popolari perché migliorano grazie ai soldi spesi per le loro ricerche ... e così via.