Estoy usando el nuevo MemoryCache en .Net 4, con un límite máximo de tamaño de caché en MB (lo he probado entre 10 y 200 MB, en sistemas con entre 1,75 y 8GB de memoria). No establezco ninguna caducidad basada en el tiempo en los objetos, ya que estoy usando el caché simplemente como un disco de alto rendimiento, y mientras haya espacio, quiero que se use. Para mi sorpresa, el caché se negó a expulsar cualquier objeto, hasta el punto de que obtendría SystemOutOfMemory
excepciones..Net 4 MemoryCache Leaks with Concurrent Garbage Collection
Me dispararon hasta perfmon, cableado mi solicitud a .Net CLR Memory\#Bytes In All Heaps
, .Net Memory Cache 4.0
y Process\Private Bytes
- de hecho, el consumo de memoria estaba fuera de control, y no hay recortes de caché se registraban.
hecho un poco de googling y stackoverflowing, descargar y adjunta la CLRProfiler, y zas : desalojos todas partes! La memoria se mantuvo dentro de límites razonables según el límite de tamaño de la memoria que había establecido. Lo ejecuté de nuevo en modo de depuración, sin desalojos. CLRProfiler nuevamente, desalojos.
Finalmente me di cuenta de que el generador de perfiles obligó a la aplicación a ejecutarse sin concurrent garbage collection (también ver útil SO Concurrent Garbage Collection Question). Lo apagué en mi app.config, y, efectivamente, ¡desalojos!
Este parece ser, en el mejor de una falta enorme de documentación para no decir: esto sólo funciona con la recolección de basura no concurrente-
imagen que, aunque desde su portado desde ASP.NET, puede que no hayan tenido que preocuparse sobre la recolección de basura simultánea
.
¿Alguien más ha visto esto? Me encantaría obtener algunas otras experiencias, y tal vez algunas ideas más educadas.
Actualización 1
he reproducido el problema dentro de un solo método: parece que la memoria caché debe estar escrito en paralelo para el desalojo de caché de prohibido hacer fuego (en el modo de recolección de desechos concurrente) Si hay algún interés, subiré el código de prueba a un repositorio público. Definitivamente me estoy haciendo hacia la parte más profunda de la CLR/GC/piscina MemoryCache, y creo que olvidé mis flotadores ...
Actualización 2
Me publicada test code on CodePlex para reproducir el problema. Además, posiblemente de interés, el código de producción original se ejecuta en Azure, como Rol de trabajador. Interesante, cambiar la configuración de concurrencia de GC en la aplicación app.config de la función no tiene ningún efecto. ¿Posiblemente Azure anula la configuración de GC como ASP.NET? Además, ejecutar el código de prueba en WPF frente a una aplicación de consola producirá resultados de desalojo ligeramente diferentes.
llevar esto a connect.microsoft.com –
Sin duda en mis tareas pendientes - de hecho, había una media llenado billete, pero luego no pudo reproducirlo en un solo método. Ahora que puedo, lo publicaré. –
El problema de Microsoft Connect se archivó aquí: https://connect.microsoft.com/VisualStudio/feedback/details/661340/memorycache-evictions-do-not-fire-when-memory-limits-are-reached. –