2010-06-11 15 views
6

Perdón si esto es más incumplimiento del servidor frente a stackoverflow. Parece estar en la frontera.¿Cómo puedo exceder el límite de memoria del 60% de IIS7 en la aplicación de almacenamiento en caché de ASP.NET

Tenemos una aplicación que almacena en caché una gran cantidad de datos de productos para una aplicación de comercio electrónico que utiliza el almacenamiento en caché de ASP.NET. Este es un objeto de diccionario con 65K elementos, y nuestros cálculos ponen el tamaño del objeto en ~ 10GB.
Problema:

  1. La cantidad de memoria consume el objeto parece estar muy por encima de nuestro cálculo de 10 GB.

  2. PREOCUPACIÓN MÁS GRANDE: Parece que no podemos usar más del 60% de los 32 GB en el servidor.

Lo que hemos tratado hasta ahora:

En machine.config/system.web (sf no permite que las etiquetas, perdón por el formato):

processModel autoConfig="true" memoryLimit="80" 

En web.config/system.web/caching/cache (sf no permite las etiquetas, perdone el formateo):

privateBytesLimit = "20000000000" (and 0, the default of course) 
percentagePhysicalMemoryUsedLimit = "90" 

Medio Ambiente: de Windows 2008R2 64 32 GB de RAM IIS7

Nada parece que nos permita superar el valor 60%. Ver captura de pantalla de taskman.

http://www.freeimagehosting.net/image.php?7a42144e03.jpg

+0

Una suposición educada: el servidor está reajustando su memoria para ajustarse a la mayor carga de trabajo que está lanzando, usando más del archivo de intercambio para compensar, o basura acumulando memoria más rápido. Algo como eso. ¿Cómo se ve la pestaña Rendimiento en Taskman a medida que aumenta la carga? ¿El tamaño del archivo de intercambio aumenta? –

+0

@Robert: el intercambio se mantiene prácticamente plano (lo cual tiene sentido, ya que es un caché en memoria). Vale la pena comprobarlo. @todos: Me pregunto si el tamaño de un solo objeto es el problema. ¿El GC requiere una cierta cantidad de "espacio de holgura" para desplazar objetos alrededor y este _un_objeto excedió eso? – evilknot

+0

¿Está intercambiando objetos dentro y fuera del diccionario? Si lo está, eso podría estar presionando al GC, ya que cada intercambio liberará un objeto que debe eliminarse en algún momento. Es posible que el GC no espere a que se quede sin memoria antes de realizar una recopilación. Algunos perfiles de memoria pueden estar en orden. –

Respuesta

1

Ha considerado el uso de una estrategia de almacenamiento en caché diferente? El almacenamiento en memoria caché integrado no es tan rico en funciones y tendrás problemas para conseguir que haga mucho más (a menos que algún gurú de IIS tenga algo de ingenioso).

Pasamos mucho tiempo trabajando en esto y nos dimos por vencidos. De hecho, utilizamos objetos más delgados para almacenar en la memoria caché y obtener los objetos más completos según sea necesario.

Cuando necesitábamos contemplar esto, investigamos Memcached y Velocity, pero nos retiramos de su implementación por el momento. Sin embargo, son más ricos en características.

¿Cómo está almacenando los elementos en la memoria caché a través del código? ¿Los está poniendo al inicio de la aplicación o después de la primera solicitud para cada uno? La razón por la que pregunto es si las claves de su caché son efectivas y que en realidad está poblando el caché una y otra vez y no recuperando nada (este puede ser el caso de un solo tipo de objeto). Logramos hacer esto una vez añadiendo la hora a una clave de caché específica de fecha, por ejemplo.

+0

Definitivamente estamos explorando otros cachés. Estamos completando el caché una vez, cuando se inicia la aplicación, y no cambia. Hemos estado viendo lo anterior, además de nCache. ¡Gracias! – evilknot

+1

+1, la memoria caché asp.net está realmente mal aquí - probablemente desee algo más y esté fuera de proceso. –

2

Un poco tarde pero estoy teniendo casi el mismo problema. El problema con la configuración memoryLimit en processModel es que parece no tener ningún efecto a pesar de estar documentado como tal.

percentagePhysicalMemoryUsedLimit parece que debería hacer algo pero no tiene ningún efecto.

privateBytesLimit="20000000000"does work though. Fui y depuré el proceso y encontré el objeto CacheMemorySizePressure y recogió el valor con éxito y lo configuró en _memoryLimit. Verificaría eso dos veces.

Otra opción es establecer un umbral de reciclaje de uso de memoria privada en el grupo de aplicaciones de IIS. Eso también debería ser recogido y anular el límite predeterminado del 60%.

Una tercera opción es usar la nueva clase MemoryCache y configurar el PhysicalMemoryLimit en ella.

Cuestiones relacionadas