pointers - tipos - Recolección de basura vs. punteros compartidos
qué es el puntero y para qué sirve (3)
¿Cuáles son las diferencias entre los punteros compartidos (como boost :: shared_ptr o el nuevo std :: shared_ptr) y los métodos de recolección de basura (como los implementados en Java o C #)? Tal como lo entiendo, los punteros compartidos hacen un seguimiento de cuántas veces las variables apuntan al recurso y automáticamente destruyen el recurso cuando el recuento llega a cero. Sin embargo, tengo entendido que el recolector de basura también administra los recursos de la memoria, pero requiere recursos adicionales para determinar si un objeto todavía se está consultando y no necesariamente destruye el recurso de inmediato.
¿Estoy en lo correcto en mis suposiciones y existen otras diferencias entre el uso de recolectores de basura y punteros compartidos? Además, ¿por qué alguien utilizaría un recolector de basura sobre un puntero compartido si realizan tareas similares pero con distintas cifras de rendimiento?
En un sistema simple recolectado de basura, nadie tendrá un puntero directo a ningún objeto; en su lugar, el código mantendrá referencias a las entradas de la tabla que apuntan a los objetos en el montón. Cada objeto en el montón almacenará su tamaño (lo que significa que todos los objetos del montón formarán una lista de enlace único) y una referencia retrospectiva al objeto en la tabla de objetos que lo contiene (o al menos está acostumbrado).
Cuando el montón o la tabla de objetos se llena, el sistema establecerá un indicador de "eliminarme" en cada objeto de la tabla. Examinará todos los objetos que conozca y, si se configuró su "indicador de eliminación", lo desarmará y agregará todos los objetos que conoce a la lista de objetos que se examinarán. Una vez hecho esto, se puede eliminar cualquier objeto cuya bandera "eliminarme" aún esté establecida.
Una vez hecho esto, el sistema comenzará al principio del montón, tomará cada objeto almacenado allí y verá si su referencia de objeto todavía apunta a él. Si es así, copiará ese objeto al principio del montón, o justo después del final del último objeto copiado; de lo contrario, el objeto se omitirá (y es probable que se sobrescriba cuando se copian otros objetos).
Esos punteros compartidos (generalmente llamados recuento de referencias) corren el riesgo de ciclos.
La recolección de basura (Marcar y Barrido) no tiene este problema.
La principal diferencia radica, como ha notado, en cuando el recurso es liberado / destruido.
Una ventaja de que un GC podría ser útil es si tiene recursos que tardan mucho tiempo en liberarse. Para una vida útil corta del programa, puede ser bueno dejar los recursos colgando y limpiarlos al final. Si se alcanzan los límites de recursos, el GC puede actuar para liberar algunos de ellos. Los punteros compartidos, por otro lado, liberan sus recursos tan pronto como el recuento de referencia llega a cero. Esto podría ser costoso para los frecuentes ciclos de adquisición-liberación de un recurso con costosos requisitos de tiempo.
Por otro lado, en algunas implementaciones de recolección de basura, la recolección de basura requiere que todo el programa pause su ejecución mientras se examina, mueve y libera la memoria. Hay implementaciones más inteligentes, pero ninguna es perfecta.