2011-12-20 17 views
8

Durante el día veo muchas colecciones de gen 2 en nuestro servicio de Windows.¿Cuándo decide GC recoger la generación 2?

¿Cuándo decide GC hacer la colección completa en lugar de recolectar solo Gen1 y Gen0 o solo Gen0?

+0

Probablemente cuando se siente presión para liberar algo de memoria. Y tal vez cuando el sistema está inactivo. Solo adivinando. –

Respuesta

9

Lea http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx y los artículos vinculados para obtener más información. En general, gen2 se recoge "cuando es necesario".

Una cosa que puede causar excesivas colecciones Gen2 es el gran montón de objetos (LOH). Cuando se llena el LOH, activará una colección completa. Si su aplicación asigna y libera muchos objetos grandes (80K o más), ese podría ser su problema.

Ver CLR Inside Out: Large Object Heap Uncovered.

Considere también utilizar el recolector de basura del servidor en su servicio. Por lo general, proporcionará un mejor rendimiento (menos colecciones). Agregue esto a su archivo app.config:

<configuration 
    <runtime> 
     <gcServer enabled="true"/> 
    </runtime> 
</configuration> 
+0

Nuestro servicio comprueba si hay trabajo por hacer y lo pone en cola en ThreadPool. Creo que esos ThreadPool Threads son los únicos que llegan hasta Gen2. No asignamos objetos grandes. Pero veo colecciones Gen2 cuando la memoria del sistema es baja. El modo de servidor AFAIK es el predeterminado cuando usa CPU multinúcleo. –

+0

@Peri Si la memoria del sistema es baja, activará un GC completo. El sistema necesita recuperar el espacio !. Es posible que desee ver la posibilidad de agregar más RAM. – Joe

+2

@Peri: No, el modo de servidor no es el predeterminado. El GC simultáneo es el predeterminado cuando usa multinúcleo, pero ese sigue siendo el GC del cliente. Si desea el GC del servidor, debe decirlo en su archivo app.config. Además, ¿estás seguro de que no asignas objetos grandes? En un sistema de 64 bits, una lista con solo 10.000 elementos requerirá una matriz de respaldo de más de 80 kilobytes. –

5

general, un colletion se activa (en virtud de cualquier generación) cuando se cumple 1 de la siguiente

  • Asignación supera el umbral. Recuerdo vagamente que esto es dinámico en función de las necesidades actuales. ¿Alguien puede confirmar/negar?
  • hay una situación de poca memoria
  • Se llama a través de GC.Collect()

Puede haber otro escenario que me falta, pero en general eso es todo. El primero es el que normalmente inicia una colección, y conisdering es (relativly) más caro recoger G2 que G0 se ve menos de ellos.


Para abordar la cuestión en el comentario:
Cada generación tiene un umbral que cuando es golpeado dará lugar a una colección. Gen0 podría ser de 5mb, y se activará cuando se llene. Después de que se ejecute GC, si tiene todavía tiene 5mb allí, creo que aumentará el límite. Si no fuera así, cada asignación activará una colección y usted tiene un problema. Gen2 podría ser 20mb (nota que estoy inventando números aquí) y la misma lógica aplica allí.

Para un ejemplo de libro de texto, veamos un escenario simple.

  1. objetos nueva aplicación asignado y todo se ponen en Gen0 para un total de 3 MB de datos. (esto es no siempre el caso, pero pretende que es)
  2. Un GC acierta, y 1 MB de eso se mueve a G1, el resto se limpia.
  3. G0 ahora es gratis, y G1 tiene 1MB en él.
  4. Se crean más objetos y ocurren más GC. Después de un tiempo, G1 se llena y algunos se mueven a G2.
  5. Los objetos permanecen allí hasta que G2 esté lleno, y luego se limpian si no están en uso. Si todavía se hace referencia a un objeto, permanecerá en G2 hasta que se pueda limpiar.

Un GC completo es costoso, y he visto pasar días sin que suceda uno. De acuerdo, esto era en un sistema con> 64 GB de memoria RAM disponible, y no había necesidad de hacerlo.

+0

¿Qué quiere decir con el primer punto? Eso, por ejemplo, cuando asigno <5MB solo recoge Gen0 (¿en cada asignación?), Gen1 cuando asigno 5-10MB y Gen2 cuando asigno más de 10MB? –

+0

No estoy seguro de entender el ejemplo. Creo que los objetos se trasladan a las generaciones anteriores cuando sobreviven al GC (todavía están vivos), no cuando la generación está "llena". –

+0

a la derecha, cuando ocurre un GC es la clave, y estar "lleno" lo pondrá en marcha (o uno de los otros 2 motivos establecidos anteriormente). Solo estaba usando eso como un ejemplo. – Joe

Cuestiones relacionadas