sobre destructores y GarbageCollector.

16/05/2007 - 21:18 por Horacio N. Hdez. | Informe spam
Hola a todos,

Mis dudas son als siguientes:

1) Cuando utilizamos C# no es posible sobreescribir el metodo
Finalize, en cambio utilizamos el simbolo ~ para declarar el
destructor. Este metodo se convierte posteriormente en una
sobreescritura de Finalize. Ahora bien, en el libro de Anders H. The
C# Programming Language se menciona que es posible proveer
Destructores mediante un metodo con la siguiente firma void Finalize.
Ahora en el siguiente codigo:

using System;

class Elve
{
~Elve()
{
Console.WriteLine("Here die an elve");
}
}

class DarkElve : Elve
{
void Finalize()
{
Console.WriteLine("Here die a dark elve");
}
}

class Program
{
public static Main()
{
Elve feanor = new Elve();
legolas=null;
System.GC.Collec();
System.GC.WaitForPendingFinalizers();
}
}

la salida es:
here die an elve

el destructor de Elve es pasado de por alto, sin embargo el codigo
MSIL es igual para ambas clases. ¿Alguien sabe por que pasa esto?

2) Esta duda es mas bien conceptual, en el libro The C# Programming
Language se enumera el ciclo de vida de un objeto teniendo en cuenta
el mantenimiento de la memoria.

1.Se crea el objeto.
2. Cuando se sale del scope y nada lo referencia (sin contar los
destructores) se separa como Listo para Destruir.
3. LLegado el momento se llama al destructor, si existe.
4.Posteriormente se verifica que este objeto no es
referenciado(incluyendo los destructores) de ser esta listo para ser
eliminado.
5.Llegado el momento la memoria dedicada al objeto es liberada.

Y en la documentacion de los destructores y Finalize() se enumera lo
siguiente:
1. Cuando un objeto es creado y tiene un destructor se coloca en una
lista.
2.Cuando se procede a recolectar "basura" si el objeto esta en la
lista, es movido hacia otra que contiene los que estan listos para
destruccion.
3. Cuando se ejecutan los destructores son al fin quitados de la
lista, y en una futura recoleccion seran eliminados.

He intentando representar esto en un organigrama, y he obtenido dos
distintos. ¿En el primer orden no se menciona nada de un segundo
proceso de recoleccion, y el ejemplo que funciona perfecto? No tengo
por que dudar de ninguna de las dos fuentes, pero no se corresponde,
al menos como yo lo veo. Si alguien pudiera aportar algo...

Gracias de antemano,

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
17/05/2007 - 08:32 | Informe spam
"Horacio N. Hdez." wrote in message
news:
[...] 1) [...]
el destructor de Elve es pasado de por alto, sin embargo el codigo
MSIL es igual para ambas clases. ¿Alguien sabe por que pasa esto?



Te falta poner la palabra "override" para indicar que sobreescribes el
método Finalize de la clase Object de la que heredas en último extremo:

class DarkElve : Elve
{
protected override void Finalize()
{
Console.WriteLine("Here die a dark elve");
}
}

Con eso ya no lo ignora, y escribe el mensaje correspondiente cuando
creas un DarkElve el el Main.

2) [...]
He intentando representar esto en un organigrama, y he obtenido dos
distintos. ¿En el primer orden no se menciona nada de un segundo
proceso de recoleccion, y el ejemplo que funciona perfecto? No tengo
por que dudar de ninguna de las dos fuentes, pero no se corresponde,
al menos como yo lo veo. Si alguien pudiera aportar algo...



La fuente correcta es la segunda, es decir, en una primera pasada del
recolector de basura los objetos que tienen un destructor se mueven a la
cola de destrución, donde un hilo separado va llamando a los destructores, y
en una segunda pasada del recolector, si el destructor ya ha terminado de
ejecutarse, entonces se libera la memoria del objeto (a no ser que dicho
destructor provoque una resurrección del objeto, en cuyo caso debería hacer
un GC.ReRegisterForFinalize para que vuelva a destruirse cuando se libero de
nuevo).

El ejemplo que has puesto funciona asi: Al hacer el GC.Collect se pega
una pasada de recolección de basura en la que el Elve pasa a la cola de
destrucción. El GC.WaitForPendingFinalizers deja parado el hilo principal
mientras un hilo en background ejecua el destructor (que escribe en consola
el mensaje correspondiente), y a continuación el programa termina con lo
cual se libera la memoria de todos los objetos, incluido el Elve que todavia
no se había liberado.
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida