5

Tengo un ciclo en mi código que genera muchas matrices de bytes [] (alrededor de 1 a 2 MB cada una), las llena de datos y luego descarta la referencia. Por lo tanto, aunque la referencia solo se lleva a cabo durante un tiempo breve de , puedo ver que el conjunto de trabajo privado está creciendo.C#: ¿Se recogerá el GC si necesita memoria o dará una excepción de memoria insuficiente?

Ahora, si trato de asignar una matriz grande (~ 400 MB) después del bucle, ¿podría obtener una excepción de falta de memoria? ¿O la asignación obligará al GC a recoger los datos transitorios?

Gracias!

Respuesta

2

Generar muchos arreglos de 1-2MB es una mala idea. Incluso si evita la situación de falta de memoria, el rendimiento realmente sufre. La asignación de muchos objetos efímeros en el montón de objetos grandes es un patrón de asignación que el GC actual no maneja bien.

Recomiendo encarecidamente reciclarlos siempre que sea posible. Implemente un grupo en el que arroje las matrices una vez que ya no las necesite. Y luego, al asignar primero, compruebe si puede satisfacer la solicitud del grupo. Ese patrón resultó en enormes beneficios de rendimiento en uno de mis programas.

Creo que la memoria completa fuerza un GC, pero si las asignaciones no administradas ocurren al mismo tiempo, aún puede obtener OOM.

+1

"La asignación de muchos objetos efímeros en el montón de objetos grandes es un patrón de asignación que el GC actual no maneja bien". ¿Te interesa ubicar tu fuente aquí? – Andy

+0

@Andy Esa es mi propia experiencia. Tuve un proyecto que tomó varias capturas de pantalla en arreglos por segundo, y el rendimiento mejoró una vez que utilicé la agrupación para reutilizar las matrices. – CodesInChaos

+0

Supongo que la razón es simplemente que es la gran cantidad de memoria por segundo que asigna que obliga a los GC todo el tiempo. Con los objetos grandes, asigna y descarta una gran cantidad de recuerdos incluso con relativamente pocas asignaciones por segundo. Y leí en alguna parte que los objetos LOH solo se recogen durante una colección Gen2, pero no estoy seguro de eso. – CodesInChaos

0

Esto realmente depende. No puede estar seguro de que el recolector de basuras lo descarte a tiempo. Con las matrices de bytes, es razonablemente seguro, pero la mayoría de los objetos se descartan demasiado tarde si los usa demasiado sin utilizar el método dispose().
Esto da como resultado excepciones de falta de memoria aunque haya descartado todas las referencias.
Si tiene problemas de experiencia, puede intentar GC.Collect(0);, aunque esto generalmente no es aconsejable.

+0

Eliminar no tiene nada que ver con GC . –

+0

¿Cómo funciona la eliminación de ayuda aquí? No creo que las matrices de bytes lo tengan. – CodesInChaos

+0

Dispose no libera memoria. Por lo general, libera recursos * no administrados *. –

1

Si le preocupa, siempre puede llamar a GC.Collect(); antes de esa gran matriz después del bucle, eso forzará una recolección de basura de todas las generaciones. Sin embargo, no entre en el circuito, a menos que no le preocupe el tiempo, ya que puede ser bastante lento (demasiado lento para un ciclo, no tanto para una sola cosa)

Cuestiones relacionadas