residuos - Suprimiendo la recolección de basura C#
recoleccion de residuos feriado capital federal (6)
A menos que pueda confirmar que el recolector de basura está desacelerando activamente el rendimiento de su aplicación, no debe tomar medidas para paralizar la funcionalidad de su entorno de tiempo de ejecución.
A juzgar por su pregunta, no ha confirmado que el GC sea un problema. Dudo mucho de que lo sea.
Optimice solo lo que necesita ser optimizado.
Mi aplicación asigna una gran cantidad de memoria (millones de objetos pequeños que suman varios gigabytes) y la conserva durante mucho tiempo.
- ¿Está .NET perdiendo el tiempo comprobando a través de todos estos datos para hacer GC en él?
- ¿Con qué frecuencia ocurre el Gen 2 GC (el que verifica todos los objetos)?
- ¿Hay alguna manera de reducir su frecuencia o suprimir temporalmente que ocurra?
- Sé exactamente cuándo estoy listo para recolectar una gran cantidad de memoria, ¿hay alguna forma de optimizar eso? Actualmente estoy llamando a GC.Collect (); GC.WaitForPendingFinalizers (); En ese tiempo.
Actualización: el contador de rendimiento "% de tiempo en GC" muestra un promedio de 10.6%.
Puedes evitar que el recolector de basura finalice cualquiera de tus objetos usando el método estático:
GC.SuppressFinalize(*your object*)
Más información aquí: enlace de texto
Solo (generalmente) sucederá cuando el GC necesite algo de memoria gen2 de todos modos (porque gen1 está lleno). ¿Estás preguntando esto de forma especulativa, o realmente tienes un problema con GC tomando una gran parte de tu tiempo de ejecución? Si no tienes un problema, te sugiero que no te preocupes por el momento, pero mantenlo vigilado con monitores de rendimiento.
Mire la propiedad System.Runtime.GCSettings.LatencyMode
.
Establecer la propiedad GCServer en true en app.config también ayudará a reducir los GC (en mi caso, 10 veces menos GC cuando está habilitado).
Puedes medir esto usando el Monitor de rendimiento. Abra perfmon y agregue los contadores de rendimiento relacionados con .NET CLR Memory. Estos contadores son específicos del proceso y con ellos puede realizar un seguimiento del número de colecciones y tamaños de las distintas generaciones y, más específicamente, del "% de tiempo en GC". Aquí está el texto de explicación para este contador:
% De tiempo en GC es el porcentaje de tiempo transcurrido que se gastó en realizar una recolección de basura (GC) desde el último ciclo de GC. Este contador suele ser un indicador del trabajo realizado por Garbage Collector en nombre de la aplicación para recopilar y compactar memoria. Este contador se actualiza solo al final de cada GC y el valor del contador refleja el último valor observado; no es un promedio
Si mira estos contadores mientras ejecuta su programa, debe responder por la frecuencia y el costo del GC debido a sus decisiones de memoria.
Aquí hay una buena discusión de los diferentes Contadores de rendimiento de GC. Parece que el 10% está en el límite correcto.
Mi aplicación ASP.NET - sistema B2B - solía comenzar a 35-40MB cuando llegó el primer usuario. Después de unos minutos, la aplicación solía crecer hasta 180 MB con 2 o 3 usuarios golpeando páginas. Después de leer las mejores prácticas de desarrollo de .net y las pautas de rendimiento de GC, descubro que el problema era el diseño de mi aplicación. No estuve de acuerdo de una vez.
Estaba horrorizado de lo fácil que podemos hacer los errores. Renuncié a muchas características y comencé a facilitar algunos objetos. Sentido:
Evite mezclar tantas páginas y controles de usuario inteligentes y comunicativos (los que tienen muchas funcionalidades que realmente existen para cada página que usa este control).
Deja de engendrar funcionalidades universales en las clases base. Algunas veces es preferible repetir. La herencia es costo
En algunas funcionalidades complejas puse todo en la misma función. SÍ, llegando a 100 líneas más. Cuando leí esta recomendación sobre la guía de rendimiento .net, no lo creí, pero funciona. Las pilas de llamadas son un problema, el uso de propiedades de clase sobre las variables locales es un problema. Las variables de nivel de clase pueden ser un infierno ...
Deje de usar clases base complejas, no debe haber clases base con más de 7 líneas. Si expandes clases más grandes en todo el framework, tendrás problemas.
Comienzo a usar más objetos estáticos y funcionalidades. Vi la aplicación que el otro chico diseñó. Todos los métodos de objetos de acceso a datos (insertar, actualizar, eliminar, seleccionar) eran estáticos. La aplicación con más usuarios simultáneos nunca llega a más de 45 MB.
Para guardar algunos proyectos, me gusta el patrón de estado de reposo. Aprendí en el mundo real, pero el autor Nygard también estuvo de acuerdo conmigo en su libro: Release IT - Diseñe e implemente software de producción lista. Él llama a tal enfoque como un patrón de estado estable. Este patrón dice que podemos necesitar algo para liberar recursos inactivos.
Es posible que desee jugar con el archivo de configuración de la máquina. En el atributo memoryLimit, indicará el porcentaje de memoria que podría alcanzarse antes de que un proceso se recicle.
También es posible que desee jugar con el archivo de configuración de la máquina. En este atributo, GC dictará el comportamiento de la máquina (Workstation GC y Server GC). Esta opción también puede cambiar drásticamente el comportamiento de consumo de la memoria.
Tuve mucho éxito cuando comencé a preocuparme por estos artículos. Espero que esto ayude.
- EDITADO EN 04-05-2014 He cambiado de opinión sobre muchas cosas debido a las mejoras de las nuevas versiones de GC y los avances de HTML 5 y framework MVC.