Barrenderos de bits, motines virtuales y otros cuentos fantásticos
C++ C#
Encuentre las 10 diferencias...
(PD: no vale usar smart pointers -por ahora-)
int foo() {
size_t n = read_size();
int *elements = malloc(n * sizeof(int));
if (read_elements(n, elements) < n) {
// oops...
return -1;
}
free(elements)
return 0;
}
private int foo()
{
return read_elements().Count() < read_size()
? -1
: 0;
}
Como consecuencia, gran parte de los desarrolladores de ultima generación solo ha trabajado con memoria en el ámbito académico y no de forma profesional
Los lenguajes clásicos (tales como C y C++) permiten (o más bien, obligan) al programador a manejar de forma explicita la memoria (alocación y liberación)
Esto ademas implica que la seguridad de tipos no esta asegurada (valga la redundancia) ya que es responsabilidad nuestra el manejo de punteros a objetos
Fallas humanas en el manejo manual de memoria nos pueden abrir la puerta a bestias indomables y difíciles de debuggear tales como:
Los últimos 2 conforman enormes riesgos de seguridad
Este (no tan) nuevo tipo de lenguajes tiene como principal característica un manejo automático de memoria, valiéndose de subsistemas para ello
El manejo automático de memoria también nos permite tener un tipado más seguro
Las áreas de memoria alocada que ya no se utilizan se conocen como basura (o garbage)
Durante la ejecución de un programa, un objeto pasa a considerarse basura si queda sin referencias
El problema de determinar si una región de memoria es basura o no es indecidible, por lo que los algoritmos existentes actúan por aproximación
El manejo de memoria depende de complejos subsistemas, lo cual nos lleva a...
Método desarrollado por John McCarthy en 1958-1959 como mecanismo de manejo de memoria de LISP
El primer GC fue Mark & Sweep, bloqueante
Actualmente decenas de lenguajes poseen o dependen de variadas técnicas de garbage collection para su gestión de memoria
Un garbage collector (de ahora en adelante, GC) debe realizar las siguientes tareas:
Para que sea eficiente, a la vez, se necesita que:
Los garbage collectors generalmente son NO deterministas
Hay 2 tipos primarios de garbage collector:
GC Roots: son las "raices" que referencian a un objeto, usualmente conformadas por:
En lenguajes de tipado seguro, una vez que un objeto es inalcanzable (queda sin raíz) no se puede volver a referenciar desde la aplicación
Un objeto esta vivo si será accedido en algún momento desde la aplicación. Este factor es indecidible, pero la accesibilidad de punteros lo es
La deteccion de basura y accesibilidad de objetos es el otro pilar de un GC. Hay varios algoritmos de detección y recolección, siendo los principales a saber:
En varios casos se combinan técnicas. Ej: los GC de Java y .NET son Mark & Sweep generacionales
Las referencias cíclicas causan fugas de memoria
Ventajas
Desventajas
Se basa en la asunción de que todos los objetos rastreables desde los GC roots son alcanzables, mientras que el resto son considerados basura
2 (+1) fases
Ventajas
Desventajas
También conocido como semispace, consiste en la copia de la memoria en uso una región de memoria libre y contigua, garantizando la compactación además de la limpieza
El uso de ambos espacios es turnado, a medida que se llena el usado actualmente
Ventajas
Desventajas
Desventajas
Basado en la premisa de que gran parte de los objetos muere joven
Los ciclos de recolección pueden abarcar algunas generaciones...
...o todas, si el trigger se propaga hasta la generación mas longeva
Ventajas
Desventajas
Incremental vs. concurrente vs. stop-the-world:
Compactante vs. no compactante