Pregunta Aplicación ASP.NET comiendo memoria. Objetos de aplicación / sesión de la razón?


Así que estamos haciendo pruebas de estrés en una aplicación ASP.NET desarrollada por una compañía externa. Estamos haciendo aproximadamente 50 solicitudes por segundo, y después de aproximadamente media hora, cada uno de los 48 procesos de trabajo (w3wp.exe) alcanza los 400 MB aproximadamente y continúa. Corriendo en IIS7.

Ahora, después de entrometerme con dotTrace, estoy bastante seguro de que hay una pérdida de memoria aquí, pero es difícil estar 100% seguro sin saber la aplicación. Cuando confrontamos a los desarrolladores con esta teoría, la descartaron después de 30 segundos diciendo que algo como "la memoria se maneja automáticamente en .NET". ¿Seguramente .NET habría recolectado basura 48x ~ 400MB si se finalizaran los datos?

De todos modos, estoy acostumbrado a trabajar con WinForms. ¿Cómo se crean exactamente las pérdidas de memoria en ASP.NET? ¿Es la ÚNICA manera de (mal) usar los objetos Aplicación y Sesión en .NET?

editar

Desde que publiqué esta pregunta aprendí que mantener referencias estáticas a objetos en los manejadores de solicitudes (ya sea una clase de servicio web, un formulario web o lo que sea) causará "fugas". Probablemente no sea el término correcto aquí, pero de todos modos ... No estaba seguro de esto, porque pensé que las clases de manejadores se eliminaron y recrearon después de cada solicitud de IIS.

Así el código como este:

public class SomeService : IService
{
    public static List<RequestData> _requestDataHistory = new List<RequestData>();
    public void SomeRequest(RequestData data)
    { 
        _requestDataHistory.Add(data);
    }        
}

Bloqueará su servidor tarde o temprano. Tal vez esto fue obvio para la mayoría de la gente, pero no para mí :-)

Aún no estoy seguro de si esto sería o no un problema si eliminara la palabra clave estática. Son instancias dispuesto después de cada solicitud?


5
2017-08-18 11:53


origen




Respuestas:


Los desarrolladores pueden tener razón. En el mundo .Net, la recolección de basura y la liberación de memoria ocurren cuando es necesario. Es decir. Si hay suficiente memoria disponible para la aplicación, puede consumir más y más, hasta que el sistema operativo no permita más asignación. No debes preocuparte por eso, a menos que realmente cause problemas.

Por supuesto, puede haber pérdidas de memoria, si la aplicación no dispone correctamente de recursos no administrados, como sockets, manejadores de archivos, etc. Mire los objetos del sistema operativo (en el administrador de tareas, puede habilitar las manijas y las columnas de objetos del usuario) para ver cómo ellos crecen.

Como dijo, el uso incorrecto de la aplicación o de la sesión también puede ser una causa.

Me pregunto por qué tendría 48 grupos de aplicaciones (procesos de trabajo). Esto es una exageración, y no necesitas eso en absoluto.

El GC gestiona la memoria por proceso, y 400 MB por proceso no es tanto. Reducir el número de grupos de aplicaciones al nr. de núcleos - 1, y luego prueba de esfuerzo la aplicación. Si luego crece demasiado, es posible que le preocupen las fugas de memoria.

Según su información adicional, sí, en ese caso, la lista de historial crecerá indefinidamente. Los objetos estáticos se crean una vez por dominio de aplicación, y viven hasta que el appdomain se activa.

No le aconsejo que elimine arbitrariamente la palabra clave estática, a menos que sepa que no rompe alguna lógica de aplicación. Investigue por qué esos datos se recopilan de todos modos y para qué se utilizan. El código también tiene otro problema: no es seguro para subprocesos, su comportamiento no está definido cuando 2 solicitudes llegaron al mismo tiempo y deciden agregar datos a esa lista.

Mejor mueva su pregunta a stackoverflow.com, ya que es una pregunta de programación y no administrativa.

Si no tiene el control de ese código, y realmente solo quiere resolver su problema de memoria, puede configurar los conjuntos de aplicaciones para que se reciclen después de un número X de solicitudes, o después de que obtengan una cantidad de memoria mayor que Y, pero nuevamente, eso no es un problema. solucion real


2
2017-08-18 13:02



Causa problemas. Los procesos de trabajo finalmente se bloquean porque no tienen memoria cuando se intenta asignar más. Estoy de acuerdo en que 400MB solo no es mucho, pero 400 * 48 MB sí. Si recortamos a un proceso de trabajo, utilizará la misma cantidad de memoria que los 48 combinados eventualmente (aunque no esté probado, no estoy en mi poder para hacerlo) - Nilzor
por favor, revisa mi edición - Sunny
Gracias por tu contribución. Supongo que el problema se ha convertido en una pregunta de programación, sí. No tengo el control del código. Como solución temporal mientras esperamos una solución, utilizaremos la técnica de reciclaje. ¡Gracias! - Nilzor


Las pérdidas de memoria, en el sentido general, son los resultados negativos / imprevistos de la lógica de codificación que no está liberando sus recursos no utilizados (o que ya no se utilizan) correctamente (o en absoluto) al mismo tiempo que se reservan recursos adicionales para nuevos / continuos requisitos de uso / procesamiento. La "huella" general de los recursos continúa creciendo, incluso aunque los requisitos reales no necesariamente aumenten si se cuenta con la "limpieza" adecuada de la utilización y liberación de recursos correctos.

En resumen, no se limita al "abuso" de la programación lógica, ya que puede deberse a supuestos incorrectos de la administración de recursos o simplemente a la falta de ella.


0
2017-08-18 13:00