martes, 18 de junio de 2013

Gestión de Memoria en C#

La evolución de los lenguajes de programación ha demostrado concentrar esfuerzos en la eficiencia, expresividad, pero sobretodo en la productividad del desarrollador. Java [1] fue uno de los primeros lenguajes en abstraer la gestión de punteros de forma transparente, dejando al programador libre de las complejidades inherentes a la gestión de memoria requerida por los punteros, los cuales llevaban registro de las referencias de las ubicaciones en memoria. Asociado a lo anterior, está el aumento de la productividad de codificación durante la construcción de software, esto consistía en liberar al programador de tareas de referenciación a ubicaciones de memoria, desde localizar el espacio hasta liberarlo para evitar fugas de memoria [2], y la edición de código poco expresivo.

En el caso particular de C#, la gestión de memoria sigue el mismo principio, y todo el proceso de gestión automática de memoria se realiza en tiempo de ejecución. Esta es una de las capacidades más sobresalientes de la CLR [3]; adicionalmente esta máquina virtual provee manejo de excepciones y seguridad de tipos [4], pues es la encargada de eliminar/liberar locaciones de memoria ocupadas por objetos creados por el programador de manera automática en tiempo de ejecución cuando éstos ya no se necesiten.

- Ciclo de vida de la gestión de memoria [6]:
  1. Creación del objeto, asignación de memoria, ejecución del constructor asociado al inicializador en la definición de la clase del objeto, objeto listo para ser usado.
  2. Si el objeto, a medida que avance el flujo de ejecución no puede ser accedido parcial o totalmente y sólo se tiene acceso al llamado al método de destrucción, entonces el objeto es candidato para eliminación.

    Además, el compilador de C# y las técnicas heurísticas del coleccionador de basura, pueden determinar la eliminación futura de objetos. e.g., si en un método se declara una variable de un tipo determinado, y se detecta que esa variable no será usada, el coleccionador de basura podrá marcarla/tratarla (aunque no arbitrariamente) como objetivo para remoción.
  3. Una vez el objeto es marcado como basura, el método destructor se encargará de eliminar el objeto; aunque es posible hacer la llamada explícita a Finalize.
  4. Cuando se haya ejecutado el deconstructor del objeto, ya se encuentra como candidato para remoción.
  5. Para finalizar, el coleccionador de basura elimina el objeto y libera la memoria asociada a los datos de ese objeto.
- Capacidades adicionales del garbage collector:
  • Rastreo del uso del objeto a lo largo de su ciclo de vida. La información del rastreo es utilizada para tomar decisiones de la gestión de memoria (locación en memoria para almacenar el objeto recién creado, como recrear la memoria del objeto, y cuando el objeto no es usado o inaccesible).
  • La especificación del garbage collector de C# implementa muchas políticas de gestión de memoria; una de las más comunes consiste en moderar las condiciones necesarias para la eliminación definitiva de un objeto y la eliminación de memoria principal, el orden de eliminación.
- Uso básico del coleccionador de basura [5]:

[Nota: El siguiente ejemplo es tomado de librería de MSDN en el enlace [5]]

Archivo PruebaColeccionadorBasura.cs [enlace alternativo]:

En la línea 29 se marca la referencia b con null y el coleccionador de basura marca tanto a a y b como candidatos para ser removidos. De forma explícita, en la línea 31, se invoca a GC.Collect(); forza la colección de basura.

Conclusiones:

Se pudo observar la utilidad de la gestión de memoria de C#. La integridad del coleccionador de basura (garbage collector) en la CLR junto con la gestión de excepciones y seguridad de tipos. La fases del ciclo de vida de un objeto y su relación con el coleccionador de basura. Un ejemplo práctico sobre la llamada explícita a GC.Collect(); para forzar la colección de basura, entre otros elementos importantes.

Glosario:

- CLR
- Garbage collector
- Java
- Memory leak
- Seguridad de tipos (type-safety)

Referencias:

[1] Java (Programming Language) - https://en.wikipedia.org/wiki/Java_(programming_language)
[2] Memory leak - http://en.wikipedia.org/wiki/Memory_leak
[3] Common Language Runtime - http://en.wikipedia.org/wiki/Common_Language_Runtime
[4] Seguridad de Tipos en C# - http://ortizol.blogspot.com/2013/06/seguridad-de-tipos-en-c.html
[5] Automatic memory management - http://msdn.microsoft.com/en-us/library/aa691138(v=vs.71).aspx
[7] C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.