Fuga de memoriaUna fuga de memoria (más conocido por el término inglés memory leak) es un error de software que ocurre cuando un bloque de memoria reservada no es liberada en un programa de computación. Comúnmente ocurre porque se pierden todas las referencias a esa área de memoria antes de haberse liberado. Dependiendo de la cantidad de memoria perdida y el tiempo que el programa siga en ejecución, este problema puede llevar al agotamiento de la memoria disponible en la computadora. Una pérdida de memoria puede provocar un aumento en el uso de la memoria, el tiempo de ejecución del rendimiento y puede afectar negativamente a la experiencia del usuario. [1]
Existen varias formas de luchar contra este problema. Una forma es el uso de un recolector de basura incluso en el caso en el que este no sea parte estándar del lenguaje. El más conocido recolector de basura usado de esta manera es el Boehm-Demers-Weiser conservative garbage collector. Otras técnicas utilizadas son la adopción de esquemas de conteo de referencias o el uso de pools de memoria (técnica menos popular, utilizada en el servidor Apache y en el sistema de versiones Subversion). También hay herramientas para "auscultar" un programa y detectar las fugas. Una de las herramientas más conocidas es Valgrind. RAII"Adquirir Recursos es Inicializar", a menudo referido por sus siglas en inglés RAII (de "Resource Acquisition Is Initialization"), es un popular patrón de diseño en varios lenguajes de programación orientados a objetos como C++, y Ada. RAII soluciona las fugas de memoria relacionando objetos con los recursos adquiridos, y automáticamente liberando los recursos cuando los objetos terminan su vida. A diferencia de la recolección de basura, RAII tiene las ventajas de: saber cuándo los objetos existen y saber cuándo no. Se puede comparar los siguientes ejemplos en C y C++: /* Versión en C */
#include <stdlib.h>
void f(int n)
{
int* array = calloc(n, sizeof(int));
realizar_otras_operaciones();
free(array);
}
// Versión en C++.
#include <vector>
void f(int n)
{
std::vector<int> array (n);
realizar_otras_operaciones();
}
La versión en C requiere que el desarrollador haga la liberación de memoria, a diferencia de la versión en C++. Esto evita la sobrecarga de los esquemas de la recolección de basura, e incluso puede ser aplicado a otros recursos como:
Fugas de memoria en lenguajes con recolector de basuraLas fugas de memoria en lenguajes como JavaScript también son comunes, por ejemplo pueden ocurrir cuando hay referencias circulares entre los objetos. Por ejemplo un objeto ventana tiene una referencia a cada uno de sus controles (botones, imágenes, etc), a su vez cada control tiene una referencia a la ventana que lo contiene. Los recolectores de memoria que usan conteo de referencias pueden no darse cuenta de que una ventana ya no es usada porque sigue habiendo referencia a ella (de sus controles). Estas fugas de memoria son muy comunes cuando se programa en forma despreocupada. Hay técnicas para evitarlas (por ejemplo eliminar alguna de las referencias para cortar el círculo). En JavaScript ocurren también referencias circulares cuando se escriben funciones dentro de otras, porque cuando una función es escrita dentro de otra se mantiene una referencia a la que la incluye (para poder usar sus variables). El concepto de clausura explica estos comportamientos. Véase tambiénReferencias
|