stringtranslate.com

Gestión manual de la memoria.

En informática , la gestión manual de la memoria se refiere al uso de instrucciones manuales por parte del programador para identificar y desasignar objetos no utilizados o basura . Hasta mediados de la década de 1990, la mayoría de los lenguajes de programación utilizados en la industria admitían la gestión de memoria manual, aunque la recolección de basura existe desde 1959, cuando se introdujo con Lisp . Hoy en día, sin embargo, los lenguajes con recolección de basura como Java son cada vez más populares y los lenguajes Objective-C y Swift brindan una funcionalidad similar a través del conteo automático de referencias . Los principales lenguajes administrados manualmente que todavía se utilizan ampliamente en la actualidad son C y C++ ; consulte Asignación dinámica de memoria de C.

Descripción

Muchos lenguajes de programación utilizan técnicas manuales para determinar cuándo asignar un nuevo objeto de la tienda gratuita. C usa la mallocfunción; C++ y Java utilizan el newoperador; y muchos otros lenguajes (como Python) asignan todos los objetos de la tienda gratuita. Determinar cuándo se debe crear un objeto ( creación de objeto ) es generalmente trivial y no presenta problemas, aunque técnicas como los grupos de objetos significan que un objeto puede crearse antes de su uso inmediato. El verdadero desafío es la destrucción de objetos : determinar cuándo un objeto ya no es necesario (es decir, es basura) y disponer que su almacenamiento subyacente se devuelva al almacén gratuito para su reutilización. En la asignación de memoria manual, esto también lo especifica manualmente el programador; a través de funciones como free()en C, o el deleteoperador en C++; esto contrasta con la destrucción automática de objetos contenidos en variables automáticas , en particular variables locales (no estáticas) de funciones, que se destruyen al final de su alcance en C y C++.

Técnicas manuales de gestión de memoria.

Por ejemplo


Gestión y corrección manual.

Se sabe que la administración manual de la memoria permite varias clases importantes de errores en un programa cuando se usa incorrectamente, en particular violaciones de la seguridad de la memoria o pérdidas de memoria . Éstas son una fuente importante de errores de seguridad .

Se sabe que los lenguajes que utilizan exclusivamente la recolección de basura evitan las dos últimas clases de defectos. Aún pueden ocurrir pérdidas de memoria (y las fugas limitadas ocurren con frecuencia con la recolección de basura generacional o conservadora), pero generalmente son menos graves que las pérdidas de memoria en los sistemas manuales.

La adquisición de recursos es inicialización

La gestión manual de la memoria tiene una ventaja de corrección, que es que permite la gestión automática de recursos a través del paradigma La adquisición de recursos es inicialización (RAII).

Esto surge cuando los objetos poseen recursos escasos del sistema (como recursos gráficos, identificadores de archivos o conexiones de bases de datos) que deben abandonarse cuando se destruye un objeto, cuando la vida útil de la propiedad del recurso debe estar vinculada a la vida útil del objeto. Los lenguajes con administración manual pueden arreglar esto adquiriendo el recurso durante la inicialización del objeto (en el constructor) y liberándolo durante la destrucción del objeto (en el destructor ), que ocurre en un momento preciso. Esto se conoce como La adquisición de recursos es inicialización.

Esto también se puede utilizar con recuento de referencia determinista . En C++, esta capacidad se utiliza aún más para automatizar la desasignación de memoria dentro de un marco que de otro modo sería manual; el uso de la shared_ptrplantilla en la biblioteca estándar del lenguaje para realizar la gestión de la memoria es un paradigma común. Sin embargo, noshared_ptr es adecuado para todos los patrones de uso de objetos.

Este enfoque no se puede utilizar en la mayoría de los lenguajes de recolección de basura (en particular, los recolectores de basura de rastreo o el conteo de referencias más avanzado) debido a que la finalización no es determinista y, a veces, no ocurre en absoluto. Es decir, es difícil definir (o determinar) cuándo o si se podría llamar a un método finalizador ; esto se conoce comúnmente como el problema del finalizador. Java y otros lenguajes de GC utilizan con frecuencia la administración manual de recursos escasos del sistema además de la memoria a través del patrón de disposición : se espera que cualquier objeto que administre recursos implemente el dispose()método, que libera dichos recursos y marca el objeto como inactivo. Se espera que los programadores invoquen dispose()manualmente según corresponda para evitar la "fuga" de recursos gráficos escasos. Dependiendo del finalize()método (cómo Java implementa los finalizadores) para liberar recursos gráficos se considera ampliamente una mala práctica de programación entre los programadores de Java y, de manera similar, __del__()no se puede confiar en el método análogo en Python para liberar recursos. Para los recursos de pila (recursos adquiridos y liberados dentro de un solo bloque de código), esto se puede automatizar mediante varias construcciones de lenguaje, como Python with, C# usingo Java try-con-recursos.

Actuación

Muchos defensores de la gestión manual de la memoria sostienen que ofrece un rendimiento superior en comparación con técnicas automáticas como la recolección de basura . Tradicionalmente, la latencia era la mayor ventaja, pero ya no es así. La asignación manual frecuentemente tiene una localidad de referencia superior . [ cita necesaria ]

También se sabe que la asignación manual es más apropiada para sistemas donde la memoria es un recurso escaso, debido a una recuperación más rápida. Los sistemas de memoria pueden "darse vueltas", y lo hacen con frecuencia, a medida que el tamaño del conjunto de trabajo de un programa se acerca al tamaño de la memoria disponible; Los objetos no utilizados en un sistema de recolección de basura permanecen en un estado no reclamado durante más tiempo que en los sistemas administrados manualmente, porque no se recuperan de inmediato, lo que aumenta el tamaño efectivo del conjunto de trabajo.

La gestión manual tiene una serie de desventajas de rendimiento documentadas :

La latencia es un punto debatido que ha cambiado con el tiempo: los primeros recolectores de basura y las implementaciones simples funcionan muy mal en comparación con la administración de memoria manual, pero los recolectores de basura modernos y sofisticados a menudo funcionan tan bien o mejor que la administración de memoria manual.

La asignación manual no sufre los largos tiempos de "pausa" que ocurren en la simple recolección de basura con parada del mundo, aunque los recolectores de basura modernos tienen ciclos de recolección que a menudo no se notan. [ cita necesaria ]

La administración de memoria manual y la recolección de basura sufren tiempos de desasignación potencialmente ilimitados: la administración de memoria manual porque desasignar un solo objeto puede requerir desasignar sus miembros y, recursivamente, los miembros de sus miembros, etc., mientras que la recolección de basura puede tener ciclos de recolección largos. Esto es especialmente un problema en los sistemas de tiempo real , donde los ciclos de recolección ilimitados son generalmente inaceptables; La recolección de basura en tiempo real es posible pausando el recolector de basura, mientras que la administración manual de memoria en tiempo real requiere evitar grandes desasignaciones o pausar manualmente la desasignación.

Referencias

Ver también

enlaces externos