data - ASP.NET MVC y EF Code First Memory Usage
pagedlist mvc (2)
Tengo una aplicación incorporada en ASP.NET MVC 3 que usa SQL CE para almacenamiento y EF CTP 5 para acceso a datos.
He implementado este sitio en un host compartido solo para encontrar que se está reciclando constantemente a medida que alcanza el límite de 100 mb que establecen en sus grupos de aplicaciones (dedicadas).
El sitio, cuando se ejecuta en modo de lanzamiento, utiliza alrededor de 110 MB de RAM.
He intentado usar SQL Server Express en lugar de CE y esto hizo una pequeña diferencia.
La única diferencia significativa es cuando eliminé EF completamente (usando un repositorio falso). Esto dejó caer el uso de memoria entre 30mb-40mb. ¿Una plantilla MVC en blanco usa alrededor de 20 mb, así que pensé que esto no es tan malo?
¿Hay algún punto de referencia para las aplicaciones MVC de ASP.NET "estándar"?
Sería bueno saber qué utilización de memoria están obteniendo otros usuarios de EF CTP, así como algunas sugerencias para las herramientas de creación de perfiles de memoria (preferiblemente las gratuitas).
Vale la pena mencionar cómo estoy manejando la vida útil de EF ObjectContext. Estoy usando sesión por solicitud y creando una instancia del ObjectContext usando StructureMap:
For<IDbContext>().HttpContextScoped().Use(ctx => new MyContext("MyConnStringName"));
Muchas gracias ben
Lo gracioso es que creo que obtuvieron su estimación de esta URL:
http://blog.whitesites.com/w3wp-exe-using-too-much-memory-and-resources__633900106668026886_blog.htm
PD: es un excelente artículo para ver y ver si estás haciendo algo que el chico esté describiendo. (Por ejemplo, el almacenamiento en caché de sus páginas)
PSS acaba de comprobar nuestro sistema y está funcionando a 50 megas actualmente. Estamos utilizando MVC 2 y EF CTP 4.
Logramos reducir nuestra huella de memoria de manera significativa. El proceso de trabajo de IIS ahora se ubica alrededor de 50 mb en comparación con los 100 mb anteriores.
A continuación se presentan algunas de las cosas que nos ayudaron:
- Compruebe los conceptos básicos. Asegúrese de compilar en modo de lanzamiento y establezca la depuración de la compilación en falso en web.config. Es fácil olvidar tales cosas.
- Utilice los símbolos DEBUG para el código de diagnóstico. Un ejemplo de esto sería cuando usas herramientas como NHProf (sí, esto me ha sorprendido antes). Lo más fácil es envolver dicho código en una directiva #if DEBUG para garantizar que no se compile en el lanzamiento de su aplicación.
- No te olvides de SQL. Los ORMs hacen que sea demasiado fácil ignorar cómo su aplicación está hablando con su base de datos. Usar el Analizador de SQL o herramientas como EFProf / NHProf puede mostrarle exactamente lo que está sucediendo. En el caso de EF, probablemente se sentirá un poco mal después, especialmente si hace un uso significativo de la carga perezosa. Una vez que haya superado esto, puede comenzar a optimizar (vea el punto a continuación).
- La carga perezosa es conveniente pero no debe utilizarse en vistas MVC (IMO). Esta fue una de las causas principales de nuestro alto uso de memoria. La página de inicio de nuestro sitio web estaba creando 59 consultas individuales debido a la carga lenta (SELECT N + 1). Después de crear un modelo de vista específico para esta página y cargar con entusiasmo las asociaciones que necesitábamos, llegamos a 6 consultas que se ejecutaron en la mitad del tiempo.
- Los patrones de diseño están para guiarlo, no para descartar el desarrollo de su aplicación. Tiendo a seguir un enfoque DDD siempre que sea posible. En este caso, realmente no quería exponer claves externas en mi modelo de dominio. Sin embargo, como EF no maneja las asociaciones de muchos a uno tan bien como NH (emitirá otra consulta solo para obtener la clave externa de un objeto que ya tenemos en la memoria), terminé con una consulta adicional (por objeto) se muestra en mi página. En este caso, decidí que podría soportar un poco de olor a código (incluido el FK en mi modelo) por el mejor rendimiento.
- Una "solución" común es lanzar el almacenamiento en caché a problemas de rendimiento. Es importante identificar el problema real antes de formular su estrategia de almacenamiento en caché. Podría haber aplicado el almacenamiento en caché de resultados a nuestra página de inicio (consulte la nota a continuación), pero esto no cambia el hecho de que tengo 59 consultas que llegan a mi base de datos cuando la memoria caché caduca.
Una nota sobre el almacenamiento en caché de salida : cuando ASP.NET MVC se lanzó por primera vez, pudimos realizar el almacenamiento en caché de anillos, es decir, el almacenamiento en caché de una página APART de una (s) región (es) específica (s). El hecho de que esto ya no sea posible hace que el almacenamiento en caché de resultados sea bastante inútil si tiene información específica del usuario en la página. Por ejemplo, tenemos un estado de inicio de sesión en el menú de navegación del sitio. Esto solo significa que no puedo usar el almacenamiento en caché de salida para la página, ya que también almacenaría el estado de inicio de sesión.
En última instancia, no existe una regla estricta sobre cómo optimizar una aplicación. La mejora más grande en el rendimiento de nuestra aplicación se produjo cuando dejamos de usar el ORM para crear nuestras asociaciones (para la parte pública de nuestro sitio) y en su lugar las cargamos manualmente en nuestros modelos de vista. No pudimos usar EF para cargarlos con entusiasmo ya que había demasiadas asociaciones (lo que resultó en una consulta desordenada de UNION).
Un ejemplo fue nuestro mecanismo de etiquetado. Entidades como BlogPost y Project pueden ser etiquetadas. Las etiquetas y las entidades etiquetables tienen una relación de muchos a muchos. En nuestro caso, fue mejor recuperar todas las etiquetas y guardarlas en caché. Luego creamos una proyección de linq para almacenar en caché las claves de asociación para nuestras entidades etiquetables (por ejemplo, ProjectId / TagId). Al crear el modelo de visualización para nuestra página, podríamos crear las etiquetas para cada entidad etiquetable sin llegar a la base de datos. Nuevamente, esto fue específico para nuestra aplicación, pero produjo una mejora masiva en el rendimiento y en la reducción del uso de la memoria.
Algunos de los recursos / herramientas que usamos en el camino:
- EFProf : para supervisar las consultas generadas por Entity Framework (prueba gratuita disponible)
- ANTS Memory Profiler (prueba gratuita disponible)
- Monitor de rendimiento de Windows (perfmon)
- Blog de Tess Ferrandez
- Mucho café :)
Si bien hicimos mejoras que nos llevaban a los límites del grupo de aplicaciones de la empresa de alojamiento (Arvixe), siento el deber de avisar a las personas que están considerando sus planes de revendedor de Windows, que tales restricciones están implementadas (ya que Arvixe no lo hace). Mencione esto en cualquier lugar al anunciar el plan). Entonces, cuando algo parece demasiado bueno para ser verdad (x ilimitado, y, z), por lo general lo es.