collector c# .net python garbage-collection

garbage collector c#



¿Cómo funciona la recolección de basura y el alcance en C#? (5)

  1. Cuando un objeto ya no tiene una referencia fuerte a él, nada sucede de inmediato. A cada objeto se le asigna una generación, 0, 1 o 2. Inicialmente, todos los objetos se colocan en la generación 0. Usando el algoritmo de marca y barrido, el recolector de basura revisará periódicamente una generación. Si la instancia todavía tiene referencias sólidas, se promueve a una generación superior hasta 2 (que generalmente se verifican con menos frecuencia). La teoría detrás de esto es que la mayoría de los objetos son generalmente de corta duración, por lo que si un objeto ha vivido lo suficiente como para llegar a la Generación 1, no es necesario verificarlo con tanta frecuencia.
  2. No hay recuento de referencias en el .NET GC. Por el contrario, utiliza la marca y barrido.

Esta pregunta ya tiene una respuesta aquí:

Estoy aprendiendo C # proveniente de python y deseo saber cómo funciona el recolector de basura en C #. Descubrí que entendí mucho más acerca de python una vez que descubrí lo que estaba haciendo detrás de escena, y deseo evitar hacer el tipo de noob Errores que cometí al principio al aprender python.

No he podido encontrar buenas explicaciones claras sobre cuándo se recolecta la basura de un artículo y me quedan preguntas como

  1. "¿Qué le sucede a un objeto cuando su última referencia queda fuera del alcance?" ¿Se recolecta la basura de ese objeto o sigue estando allí cuando vuelve al ámbito en el que se definió?
  2. "¿En qué momento se reduce el número de referencias?" Haciéndome preguntarme si incluso usa el conteo de referencias o alguna otra técnica ...

Las respuestas a estas preguntas, o incluso mejor, una visión general clara y clara de lo que realmente está sucediendo ganarán cookies (o upvotes), e incluso mejor si su respuesta lo compara con la forma en que Python hace las cosas. No me interesa lo que es mejor, solo los detalles. También las respuestas en mi publicación original en programmers.stackexchange serían muy apreciadas ...


El ''recolector de basura'' es realizado por el recolector de basura que forma parte de CLR en el marco .NET.

Es un proceso automático de liberar memoria mediante la identificación de objetos que ya no son necesarios, a diferencia de c, c ++, donde el programador explícitamente tuvo que desasignar la memoria.

Cómo funciona el recolector de basura

Busca periódicamente en la memoria, es decir, el montón administrado y libera la memoria ocupada por objetos muertos.

el objeto muerto se identifica si su código no lo puede alcanzar.

Implementación

Hay 3 formas en las que puedes implementar la administración de memoria:

GC funciona solo para recursos administrados, por lo tanto .NET proporciona Dispose y Finalize para liberar recursos no administrados como flujo, conexión de base de datos, objetos COM, etc.

1) Disponer

Dispose debe llamarse explícitamente para los tipos que implementa IDisposable.

El programador debe llamar a esto usando Dispose () o mediante Using construct

Use GC.SuppressFinalize (esto) para evitar llamadas a Finalizer si ya ha usado dispose ()

2) Finalizar o Distructor

Se llama implícitamente después de que el objeto es elegible para la limpieza, el finalizador para los objetos se llama secuencialmente por el subproceso finalizador.

La desventaja de la implementación del finalizador es que la recuperación de la memoria se retrasa, ya que el finalizador para tales clases / tipos debe llamarse limpieza previa, por lo que es una suma adicional para recuperar la memoria.

3) GC.Collect ()

El uso de GC.Collect () no necesariamente pone GC para la recopilación, GC aún puede anular y ejecutar cuando quiera.

también GC.Collect () solo ejecutará la parte de seguimiento de la recolección de basura y agregará elementos a la cola del finalizador, pero no llamará a los finalizadores para los tipos, que son manejados por otro hilo.

Use WaitForPendingFinalizers si desea asegurarse de que todos los finalizadores se hayan ejecutado después de invocar GC.Collect ()

Consulte la publicación en mi blog donde tengo este artículo: - Recolección de basura en .NET


El motor dotnet GC es un motor de marca y barrido en lugar de un motor de contador de referencia como está acostumbrado en python. El sistema no mantiene un recuento de referencias a una variable, sino que ejecuta una "colección" cuando necesita recuperar la RAM, marcando todos los punteros que están actualmente disponibles y eliminando todos los punteros que no son accesibles (y por lo tanto están fuera de alcance).

Puedes encontrar más información sobre cómo funciona aquí:
http://msdn.microsoft.com/en-us/library/ee787088.aspx

El sistema encuentra objetos "accesibles" al comenzar en ubicaciones "raíz" específicas, como los objetos globales y los objetos en la pila, y rastrea todos los objetos referenciados por ellos y todos los objetos referenciados por ellos, etc., hasta que se construye un árbol completo. . Esto es más rápido de lo que parece.


En algún momento indeterminado en el tiempo después de que la última referencia a un objeto desaparezca, el objeto se recopilará.

La segunda parte de tu primera pregunta no tiene sentido.
Si puede volver al ámbito en el que se definió un objeto (por ejemplo, una expresión lambda), obviamente todavía hay una referencia.

El GC no usa el conteo de referencias en absoluto.
Más bien, utiliza un algoritmo de marca y barrido .


La recolección de basura no se desencadena por referencias que están fuera del alcance. La recolección de basura generalmente se activa cuando se asigna almacenamiento para nuevos objetos, específicamente cuando se agota el presupuesto de la generación cero. Es decir, puede haber un retraso significativo entre cuando los objetos son elegibles para la recolección de basura y cuando realmente se recolectan. Como otros ya han señalado, el CLR no utiliza el conteo de referencias. En su lugar, emplea un enfoque de marca y barrido.

Una buena fuente de información sobre todos los detalles sobre cómo funciona la recolección de basura es el libro CLR de Jeffrey Ricther a través de C # . El libro explica en detalle cómo se divide el montón y cómo funciona la recolección de basura. Muy recomendable si está interesado en los detalles de implementación de .NET.