Su pregunta contiene varios mitos de administración de memoria:
> El objeto se liberará tan pronto como no tenga referencia.
La gente suele afirmar eso, pero no es cierto. Ver: mitos sobre la gestión de la memoria: rapidez
- ¿Por qué Google no tiene un servidor centralizado con casi todas las especificaciones y controladores de dispositivos OEM de Android para actualizaciones centrales de Android?
- ¿Cuál debería ser el enfoque de un profesional que trabaja para aprender el desarrollo de Android?
- ¿Está bien copiar y pegar código mientras se desarrolla una aplicación de Android?
- Cómo hacer una copia de seguridad de todo tu Android, incluidas las aplicaciones reales, el firmware o simplemente todo
- Cómo ver archivos SQLite
> El conteo de referencias basado en GC no causará un alto.
La gente a menudo afirma eso, particularmente en el contexto del recolector de basura ARC de Apple, pero tampoco es cierto. Cuando se disminuye un recuento de referencia, los recuentos de referencia del cierre transitivo de todos los objetos accesibles desde él, pero también se disminuyen. En la mayoría de las implementaciones, esto se hace inmediatamente en un ciclo cerrado. Por lo tanto, cuando la última referencia a una colección compuesta por un gran número de objetos asignados al montón cae fuera de alcance, el recolector de basura de conteo de referencias se encuentra allí, decrementando todos sus recuentos y recuperando toda su memoria. Eso incurre en una pausa ilimitada, potencialmente más larga que cualquier pausa en la que pueda incurrir un colector de rastreo generacional incremental típico.
Puede ver este efecto en Mathematica (que se cuenta por referencia) si crea un árbol grande y le pone una referencia desde un símbolo y luego establece el símbolo en nulo, Mathematica se detendrá (a veces por segundos) mientras su colector de basura cuenta de referencia Limpia toda la memoria. Cuando se usa Mathematica, no es raro que se detenga por largos períodos de tiempo mientras hace un recuento de referencias y es muy frustrante. Si compara con OCaml (que utiliza un recolector de basura de rastreo), las pausas en las que OCaml incurre son mucho más cortas que las de Mathematica.
En cuanto a su pregunta principal:
> ¿Por qué Java no utiliza GC de conteo de referencias?
La respuesta es porque el seguimiento de la recolección de basura es mejor para la mayoría de los programas y la mayoría de los programadores la mayor parte del tiempo. Las dos desventajas principales del recuento de referencias son que es muy lento (vea shared_ptr de Boost hasta 10 veces más lento que la recolección de basura de OCaml) y que pierde ciclos. Puede acelerar el conteo de referencias pero solo sacrificando sus otros beneficios (por ejemplo, la rapidez).