Compartir a través de


Aspectos rápidos para comprobar cuándo experimenta niveles altos de memoria en ASP.NET

En este artículo se describen los aspectos rápidos que se deben comprobar al experimentar memoria alta en Microsoft ASP.NET.

Versión original del producto: ASP.NET
Número de KB original: 893660

Este artículo comenzará con algunos problemas comunes, acciones para solucionar estos problemas y una breve explicación de por qué estas situaciones pueden causar problemas.

columna ASP.NET Support Voice (Voz de soporte técnico)

En la columna De abril de 2005 Support Voice , proporcionamos accidentalmente un vínculo al archivo incorrecto. En lugar de vincular a una descarga para el servicio web, vinculamos al archivo XML devuelto por el servicio web. Ese vínculo se ha corregido. Si desea revisar el artículo con el archivo correcto adjunto, consulte Actualizaciones de página dinámicas mediante XMLHTTP.

¿Qué se considera memoria alta?

Obviamente, esta pregunta depende del volumen y la actividad de aplicaciones específicas. En general, la memoria alta es cuando la memoria del proceso de trabajo de ASP.NET (Aspnet_wp.exe) o del proceso de trabajo de Internet Information Services (IIS) (W3wp.exe) aumenta constantemente y no vuelve a un nivel cómodo.

En términos generales, un nivel cómodo sería inferior a 600 MB en el espacio de direcciones de memoria de usuario predeterminado de 2 GB. Una vez que el nivel de memoria es mayor que ese nivel cómodo, estamos haciendo menos de lo que deberíamos ser. Este comportamiento puede afectar a otras aplicaciones que se ejecutan en el sistema.

La clave es comprender que algunas aplicaciones requieren más memoria que otras. Si supera estos límites, puede agregar más memoria o agregar otro servidor a la granja de servidores web (o considerar una granja de servidores web). También se recomienda generar perfiles en estos casos. Puede permitir a los desarrolladores crear aplicaciones más ajustadas. En este artículo, estamos viendo una situación en la que se ve constantemente el aumento de la memoria hasta que el servidor deja de funcionar.

Configuración de la aplicación para la depuración

Una razón para la memoria alta que vemos aquí en Soporte técnico es cuando tiene la depuración, el seguimiento o ambos habilitados para la aplicación. Habilitar la depuración y el seguimiento es una necesidad al desarrollar la aplicación. De forma predeterminada, al crear la aplicación en Visual Studio .NET, verá el siguiente atributo establecido en el archivo Web.config :

<compilation
 ...
 debug="true"
 />

o

 <trace
 enabled="true"
 ...
 />

Además, cuando realice una compilación final de la aplicación, asegúrese de hacerlo en modo de versión, no en modo de depuración. Una vez que esté en producción, la depuración ya no debe ser necesaria. Realmente puede ralentizar el rendimiento y comer la memoria. Establecer este atributo significa que se cambian algunas cosas sobre cómo se controla la aplicación.

En primer lugar, la compilación por lotes se deshabilitará, incluso si se establece en este compilation elemento. Esto significa que crea un ensamblado para cada página de la aplicación para que pueda dividirlo. Estos ensamblados se pueden dispersar aleatoriamente en el espacio de memoria, lo que dificulta la búsqueda del espacio contiguo para asignar memoria.

En segundo lugar, el executionTimeout atributo (<elemento httpRuntime>) se establece en un número alto, reemplazando el valor predeterminado de 90 segundos. Es correcto al depurar, ya que no se puede agotar el tiempo de espera de la aplicación mientras recorre pacientemente el código para encontrar los errores. Sin embargo, es un riesgo significativo en producción. Significa que si tiene una solicitud no autorizada por cualquier motivo, se mantendrá en un subproceso y continuará cualquier comportamiento perjudicial durante días en lugar de pocos minutos.

Por último, creará más archivos en la carpeta Archivos ASP.NET temporales. Y el System.Diagnostics.DebuggableAttribute (espacio de nombres System.Diagnostics se agrega a todo el código generado, lo que puede provocar una degradación del rendimiento.

Si no obtiene nada más de este artículo, espero que obtenga esta información. Dejar habilitada la depuración es incorrecta. Vemos este comportamiento con demasiada frecuencia y es tan fácil de cambiar. Recuerde que se puede establecer en el nivel de página. Asegúrese de que todas las páginas no la establezcan.

Concatenación de cadenas

Hay aplicaciones que compilan la salida HTML mediante código del lado servidor y simplemente compilan una cadena HTML grande para enviar al explorador. Está bien, pero si va a crear la cadena mediante + y & concatenación, es posible que no sepa cuántas cadenas grandes está compilando. Por ejemplo:

string mystring = "<html>";
mystring = mystring + "<table><tr><td>";
mystring = mystring + "First Cell";
mystring = mystring + "</td></tr></table>";
mystring = mystring + "</html>";

Este código parece lo suficientemente inofensivo, pero esto es lo que está almacenando en la memoria:

<html>
<html><table><tr><td>
<html><table><tr><td>First Cell
<html><table><tr><td>First Cell</td></tr></table>
<html><table><tr><td>First Cell</td></tr></table></html>

Puede pensar que solo está almacenando la última línea, pero está almacenando todas estas líneas. Puede ver cómo podría salir de la mano, especialmente cuando se crea una tabla grande, quizás haciendo un bucle a través de un conjunto de registros grande. Si es lo que está haciendo, use nuestra System.Text.StringBuilder clase para que solo almacene la cadena grande. Consulte Uso de Visual C# para mejorar el rendimiento de la concatenación de cadenas.

.NET Framework Service Pack 1 (SP1)

Si aún no está ejecutando .NET Framework SP1, instale este SP si tiene problemas de memoria. No voy a entrar en gran detalle, pero básicamente, con SP1 ahora estamos asignando memoria de una manera mucho más eficaz. Básicamente, estamos asignando 16 MB a la vez para objetos grandes en lugar de 64 MB a la vez. Todos nos hemos movido, y todos sabemos que podemos empaquetar mucho más en un coche o camión si estamos usando muchas cajas pequeñas en lugar de unas pocas cajas grandes. Es la idea aquí.

No tenga miedo de reciclar periódicamente

Los grupos de aplicaciones se reciclan en IIS cada 29 horas de forma predeterminada. El proceso de Aspnet_wp.exe continuará hasta que finalice la tarea, reinicie IIS o reinicie el equipo. Este comportamiento significa que este proceso podría ejecutarse durante meses. Es una buena idea que algunas aplicaciones simplemente reinicien el proceso de trabajo cada par de días o así, en un momento conveniente.

Preguntas que debe formularse

El anterior era todo lo que se puede corregir rápidamente. Sin embargo, si tiene problemas de memoria, formule estas preguntas:

  • ¿Estoy usando muchos objetos grandes? Más de 85 000 KB se almacenan en un montón de objetos de gran tamaño.

  • ¿Estoy almacenando objetos en estado sesión? Estos objetos permanecerán en memoria durante mucho más tiempo que si se usan y se eliminan.

  • ¿Estoy usando el Cache objeto? Cuando se usa sabiamente, es una gran ventaja para el rendimiento. Pero cuando se usa de forma imprudente, termina con mucha memoria usada que nunca se libera.

  • ¿Estoy devolviendo recordsets demasiado grande para una aplicación web? Nadie quiere ver 1000 registros en una página web. Debe diseñar la aplicación para que nunca obtenga más de 50 a 100 registros en un viaje.

Depuración

No entraré en la configuración de WinDbg. Pero puede usar los siguientes comandos para ver qué es exactamente en la memoria, si desea solucionar problemas más complicados.

!eeheap -gc

Este comando le mostrará la cantidad de memoria administrada que tiene. Si este valor es alto, hay algo que el código administrado está compilando.

!dumpheap -stat

Este comando tardará bastante tiempo en ejecutarse, incluso horas si la memoria es grande. Pero este comando le proporcionará una lista de todos los objetos, el número de cada tipo y la cantidad de memoria que usa cada uno. (Por ejemplo, para la StringBuilder clase , verá muchos System.String objetos)

Una vez que haya encontrado un objeto que toma mucha memoria, profundice con el comando siguiente:

!do <addr>

Puede obtener la dirección del objeto que busca en el dumpheap comando .

Intentaremos incorporar más formas de usar esta herramienta de diagnóstico para situaciones específicas en estas columnas. ¡Háganos saber si estamos haciendo un buen trabajo!

Artículos de memoria y rendimiento

Garbage Collector Basics and Performance Hints (Conceptos básicos del recolector de elementos no utilizados y sugerencias de rendimiento)

Desarrollo de aplicaciones ASP.NET de alto rendimiento

ASP.NET Monitor de rendimiento y Cuándo alertar a los administradores

Mejora del rendimiento y la escalabilidad de aplicaciones .NET