lunes, 21 de marzo de 2011

Referencias acerca del uso del Garbage Collector en .NET

Buscando referencias en cuanto al uso de los destructores en C# me encontré estos fragmentos del libro Advanced C# Programming de Paul Kimmel donde en el capítulo 1 pag 18 habla acerca de la destrucción no determinística y Garbage Collector, fragmento que copio tal cuál se encuentra en el libro:


C# uses non-deterministic destruction. The CLR implements a garbage collector that cleans up memory when objects are no longer used. This means that you don’t have to worry as much about destructors in C# as you do in C++ or Delphi.
The garbage collector will call the destructor for your objects when they are no longer needed. The destructor will call any Finalize method. You can force garbage collection by calling GC.Collect, but this is not a recommended process. The garbage collector suspends any running threads, which can cause performance problems. Besides, the garbage collector will do a good job of determining when to run.


De nuevo en el en el capítulo 3 pag 76, recalca la importancia de que no es una buena práctica, fragmento que copio tal cuál se encuentra en el libro



Control Dispose Methods C# is a .NET language. I state the obvious as a way to segue into a subject that may not be obvios. Languages like Object Pascal or C++ use deterministic construction and destruction. This means that the programmer is responsible for both creating and destroying objects.
.NET employs non-deterministic destruction.This means that the programmer is not responsible for destroying objects.The gargabe collector will clean up objects for you. As a result, you will write code that invokes the new operator, but there is no equivalent free operator.
NOTE: You can invoke the garbage collector explicitly by calling GC.Collect, but this is not a recommended practice.


Aunque la biblioteca de la universidad tiene la edición 2002 y no sé si en las ediciones actuales haya cambiado, considero que es interesante lo que menciona además que un amigo y compañero de trabajo me pregunto hace algunos años si era posible invocar a voluntad el Garbage Collector a lo cual respondí por lógica que sí porque ya había visto la clase System.GC y algo había leído algo al respecto pero en ese momento no sabía bien acerca de sus implicaciones y no había recordado la fuente.


domingo, 20 de marzo de 2011

Uso de Destructores en C#

En lenguajes orientados a objetos como C#,C++ o Java los objetos tienen un ciclo de vida el cual inicia cuando se crea el objeto mediante un constructor y acaba cuando se termina el objeto mediante un destructor.
Por ejemplo con la palabra reservada new, llamamos al constructor de un
objeto del tipo router:



El uso de constructores es igual en C# como lo es en C++ y Java, donde sino especificamos el constructor, el compilador se encarga de crearlo ya que una de sus responsabilidades es la llamada a un constructor el cual como un estándar tomado de C++ el constructor tiene el mismo nombre que la clase.
De igual forma la clase puede tener el constructor predeterminado sin argumentos, como un constructor personalizado, por ejemplo en el siguiente código:


En C# a diferencia de C++ existe el Garbage Collector (recolector de basura) que se encarga de destruir los objetos que fueron creados y ya no son utilizados, por lo que el programador no es responsable de liberar recursos asignando un destructor a cada objeto.


Sin embargo hay casos en C# donde los destructores son necesarios para objetos que hacen uso de recursos no administrados (unmanaged resources) como las conexiones hacia las bases de datos o el uso de archivos.
Los destructores a diferencia de los constructores no se heredan, no pueden recibir parámetros y no pueden sobrescribirse.
La sintaxis de un destructor es con el mismo nombre que el constructor solo se agrega una ~ como prefijo, como se muestra en el siguiente código:



A continuación el programa principal para ejemplificar los destructores

En este ejemplo el código dentro del destructor imprime un mensaje en la consola lo cual es algo trivial, esto es importante ya que en la mayoría de la documentación que hablan acerca de destructores en C# señalan que deben usarse con extremo cuidado.Hay ciertas reglas acerca de su uso:



  1. Se debe tener presente es nunca utilizar destructores en managed code (código manejado) ya que representa un problema de desempeño para el garbage collector, ya que a diferencia de C++ el objeto no es destruido inmediatamente cuando es ejecutado el destructor.

  2. En lugar de destructores utilizar Close() o Dispose().

  3. NUNCA poner código en el destructor que realice cambios críticos al ambiente o bien código que utilice recursos, es decir los destructores se usaron para liberar no para utilizar.

  4. No se debe hacer referencia a otros objetos dentro del destructor.

  5. Nunca llames a un constructor de forma directa, el garbage collector
    lo invoca de forma automática, si se requiere liberar recursos de forma
    determinística lo recomendable es usar la interfaz IDisposable.



Es posible invocar y controlar el Garbage Collector vía los métodos estáticos de la clase System.GC, pero no es recomendable ya que se activa para todas las aplicaciones que utilicen recursos en ese momento no únicamente para la aplicación que lo invoco, además que debemos de conocer los métodos no determinísticos para la liberación de memoria.
A continuación la salida del programa