asp.net caching memory heap unmanaged-memory

¿Por qué(y cómo) el caché de ASP.NET se almacena en la memoria no administrada?



caching memory (1)

Bien, todos los expertos de ASP.NET: he usado el reflector para ver la implementación del caché de ASP.NET (que se encuentra en HttpRuntime.Cache y HttpContext.Current.Cache ) usa un Hashtable internamente para mantener el caché.

Sin embargo, los datos se almacenan en la memoria no administrada. Esto es muy extraño ya que no pude ver los datos almacenados en la memoria no administrada. Sin embargo, al escribir una aplicación web muy simple que inserta una porción de matriz de bytes en el caché, podemos ver esto:

  • Bytes privados: 460MB
  • Bytes en todos los montones: 150MB

=>

Memoria gestionada: 150 MB

Memoria no administrada: 310 MB

Básicamente, estoy llamando a la aplicación muchas veces (cada aumento es de 1000x solicita cada una poniendo 64KB byte vacío [] en la memoria caché). Así que el que más ha crecido es el de bytes privados (memoria total) en lugar de bytes en todos los montones (memoria administrada). Sin embargo, espero que la memoria administrada crezca en línea con la memoria total, ya que estoy agregando objetos al montón administrado mediante Hashtable.

¿Podría explicar este comportamiento?

ACTUALIZAR

Como dijo Simon, el valor de los bytes en todos los montones solo cambia después de una recolección de basura: cambié el código para inducir la recolección de basura y actualizó los contadores. El aumento en la memoria del montón de Gen 2 es EXACTAMENTE igual a la cantidad de memoria agregada. Sin embargo, la memoria no administrada es todavía mucho mayor. En este ejemplo, Heap 2 solo tenía 96 MB, mientras que la memoria total era de 231 MB.


Los # Bytes in all Heaps solo se actualizan cuando se ejecuta la recolección de basura, mientras que los Private Bytes están disponibles a una tasa de actualización mucho más rápida. (No estoy seguro de dónde proviene ese número, internamente, y con qué frecuencia se actualiza).

La cantidad de Private Bytes aumenta justo después de las 17:42:45. Esta cantidad parece coincidir con el salto de valor de # Bytes in all Heaps montones a aproximadamente 17:43:10. Parece que tomó 20-25 segundos antes de que se realizara cualquier recolección de basura y actualizó el # Bytes in all Heaps contadores de # Bytes in all Heaps .

Es difícil averiguar cómo funcionan las asignaciones de memoria a partir de unos pocos minutos de contadores de rendimiento presentados en una captura de pantalla. ;) Continúe con su prueba y vea cómo funcionan sus expectativas durante un período de tiempo más largo.

TL; DR: la cantidad de bytes administrados debe correlacionarse con los bytes privados, pero el contador administrado solo se actualizará durante una recolección de basura.

Pequeña nota del OP: Como dice esta respuesta, el retraso en la memoria se puede explicar completamente retrasando el GC. El hecho de que la memoria no administrada también surja no fue mi pregunta. Así que gracias @Simon.