Crear objetos en C# significa que el CLR (Common Language Runtime) asigna memoria del montón para ser usada por el objeto. Esto se repite para cada creación consecutiva de un objeto. El límite es teóricamente la memoria disponible en el sistema. Esto significa que hay un límite, y necesitamos considerar otras aplicaciones que puedan necesitar utilizar estos recursos. La memoria necesita ser liberada de vez en cuando, cuando la aplicación ya no la necesita. La única responsabilidad del recolector de basura es la asignación y recuperación de este precioso recurso.
Cuando se crea un nuevo proceso se le asigna un espacio virtual separado. Este viene de la memoria física y es usado por todos los demás procesos del sistema. Cada programa utiliza un espacio virtual y no hay una interacción directa con la memoria física. El recolector de basura está trabajando en esta misma memoria virtual para asignar y reclamar la memoria.
Hay tres bloques que existen en la memoria virtual:
- Libre – Espacio vacío
- Reservado – Espacio ya asignado
- Comprometido – Esto es un regalo a la memoria física y no puede ser usado para la asignación de espacio
Hay un concepto llamado Generación que nos revela el funcionamiento interno de la recogida de basura. Hay tres generaciones que separan diferentes tipos de objetos en distintas categorías
Categorías de generación:
- Generación (Cero) – Alberga objetos de corta vida, objetos temporales; el recolector de basura es el más frecuente en este reino.
- Generación (Uno) – Un amortiguador entre Cero y Dos.
- Generación (Tres) – Mantiene los objetos de larga vida como variables estáticas y globales que necesitan persistir por un cierto tiempo.
Los objetos que no se recogen en Cero se trasladan a Uno , estos se llaman supervivientes. Entonces los objetos que no se recogen en Uno llegan a Dos . Este es el reino final que un objeto puede alcanzar.
El recolector de basura determina si un objeto está vivo:
- Recoger todas las manijas de un objeto que se asignan por código de usuario o por CLR.
- Manteniendo un seguimiento de los objetos estáticos al ser referenciados a otros objetos.
- Usando la pila proporcionada por el caminante de la pila y el JIT.
La recolección de basura puede ocurrir de estas maneras:
- Cuando la memoria virtual se está agotando en el espacio – Automático.
- Cuando la memoria asignada ha sobrepasado el umbral aceptable, la asignación del umbral se incrementa – Automático.
- Cuando los métodos GC.Collect() se llaman explícitamente – Manual.
Hay dos términos cruciales que debemos tener en cuenta antes de saltar a los destructores. El primer concepto es el de los objetos administrados y el segundo es el de los objetos no administrados .
Estamos hablando de un objeto administrado cuando este objeto está bajo el alcance de CLR; es código .NET puro que es administrado por tiempo de ejecución. Cualquier cosa que provenga de .NET como clases, estructuras de datos básicos como cadenas, enteros, etc… se denomina código administrado.
Estamos hablando de objetos no administrados cuando el objeto está fuera del control de las librerías .NET y no es administrado por el CLR. Se trata de objetos como los objetos COM, los flujos de archivos y de red, los objetos de conexión, etc…
La liberación de recursos ligados al código no administrado es más compleja que el código administrado . El recolector de basura sólo es capaz de rastrear estos recursos pero está fuera del alcance de liberarlos.
Formas de limpiar el código no administrado:
- Implementar la interfaz IDisposable y el método de eliminación.
- bloque de $0027uso$0027