Comencemos por postular que la memoria es, con diferencia (docenas, cientos o incluso miles de veces) más común que todos los demás recursos combinados. Cada variable, objeto, miembro de objeto necesita un poco de memoria asignada y liberada más adelante. Por cada archivo que abra, crea decenas de millones de objetos para almacenar los datos extraídos del archivo. Cada secuencia TCP va junto con un número ilimitado de cadenas de bytes temporales creadas para escribirse en la secuencia. ¿Estamos en la misma página aquí? Excelente.
Para que RAII funcione (incluso si tiene punteros inteligentes listos para cada caso de uso bajo el sol), debe obtener la propiedad correcta. Debe analizar quién debe poseer este o aquel objeto, quién no debe hacerlo y cuándo debe transferirse la propiedad de A a B. Claro, puede usar la propiedad compartida para todo , pero entonces estaría emulando un GC a través de punteros inteligentes. En ese momento, es mucho más fácil y rápido incorporar el GC al lenguaje.
La recolección de basura lo libera de esta preocupación por el recurso más utilizado, la memoria. Claro, aún necesita tomar la misma decisión para otros recursos, pero esos son mucho menos comunes (ver arriba), y la propiedad complicada (por ejemplo, compartida) también es menos común. La carga mental se reduce significativamente.
Ahora, nombra algunos inconvenientes para hacer que se recojan todos los valores. Sin embargo, la integración de GC y tipos de valores seguros para la memoria con RAII en un idioma es extremadamente difícil, por lo que ¿quizás sea mejor migrar estas compensaciones por otros medios?
La pérdida de determinismo resulta no ser tan mala en la práctica, porque solo afecta la vida del objeto determinista . Como se describe en el siguiente párrafo, la mayoría de los recursos (aparte de la memoria, que es abundante y puede reciclarse de manera bastante perezosa) no están sujetos a la vida útil de los objetos en estos idiomas. Hay algunos otros casos de uso, pero son raros en mi experiencia.
Su segundo punto, la gestión manual de recursos, se aborda hoy en día a través de una declaración que realiza una limpieza basada en el alcance, pero no combina esta limpieza con el tiempo de vida del objeto (por lo tanto, no interactúa con el GC y la seguridad de la memoria). Esto está using
en C #, with
en Python, try
-with-resources en versiones recientes de Java.