2009-05-27 8 views
13

Estoy volviendo a leer CLR via C# en este momento y tengo algunas preguntas sobre la recolección de basura en .NET. En el libro, después de llenar la Generación 0, se inicia la recolección de elementos no utilizados y mueve todas las referencias de objeto pendientes a la Generación 1.¿Qué sucede durante la recolección de basura si se llena la generación 2?

Lo mismo ocurre cuando se llena la Generación 1. Pero, ¿qué sucede cuando se llena la segunda generación? No hay otras generaciones para mover referencias. ¿El CLR expande el tamaño de la Generación 2?

+0

No olvide que los objetos grandes (85,000 bytes o más) comenzarán en la Generación 2. – RichardOD

Respuesta

20

Sí, expandirá el tamaño de la Generación 2 si puede. Si no hay más espacio disponible, obtendrá un OutOfMemoryException.

3

Las diferentes generaciones de recolección de basura no se tratan de tener un tamaño particular sino de la antigüedad de la basura. Ninguna de las generaciones tiene limitaciones de tamaño que yo sepa.

3

Según tengo entendido, solo hay un montón (irónicamente, generalmente se lo representa como una pila). Los objetos se promocionan a la generación 1 no cuando se llena la generación 0, sino cuando sobreviven a una colección. En resumen, las referencias no se "mueven", la ubicación utilizada para identificar dónde se mueve la generación termina.

Cuando la pila se acerca a estar lleno, algunas cosas ocurren:

  1. Cada generación se recoge, a partir de 0 y terminando con 2.
    • Si la recolección de la generación 0 es suficiente, no va a recoger la generación 1 y 2.
    • Si la recolección de la generación 0 no es suficiente, pero la recolección de la generación 1 es, no va a recoger la generación 2.
  2. El montón se compacta (vacíos se eliminan)
  3. Promover generaciones
    • Generación 1 supervivientes etiquetados como la generación 2.
    • Generación 0 supervivientes etiquetados como la generación 1.

Los objetos que sobreviven a la colección se mueven luego a la generación 0 (si este es su primer ciclo de recolección) o la generación 2 (si han sobrevivido a más de una colección). Esto se hace por el bien de la eficiencia, para garantizar que no tratemos constantemente de recolectar objetos de larga vida.

No se queda sin espacio en formas específicas de generación. See this article para una buena explicación.

+0

No creo que haya ningún etiquetado de objetos como tal. El CLR realiza un seguimiento de qué segmentos son utilizados por las diferentes generaciones, por lo que es al revés. El CLR puede determinar la generación de un objeto por su ubicación en el montón administrado. –

+0

@Brian, lo siento si no estaba claro, quise decir que el tiempo de ejecución realiza un seguimiento de dónde termina cada generación, de modo que los objetos añadidos al montón "por encima" pertenecen a una generación inferior. Estoy seguro de que simplifico demasiado, pero tiene razón, no hay "seguimiento" por objeto de qué generación se trata. –

+0

La recolección de basura se ejecuta cuando la generación cero está llena, por lo que creo que no hay ningún error. – spkenny

Cuestiones relacionadas