Sinceramente Fernando, un espectaculo esa respuesta ... clarisimo lo tuyo
.... y admirable.
 
Bien, esto explica por que tengo un OutOfMemory con 78mb libre del Sistema
Operativo.
 
Lo que me queda es forzar el reciclado para mantener mayor memoria libre del
sistema operativo o poner otro banco de memoria.
 
Ahora, respecto del reciclado, en el processmodel esta configurado para
reciclar al 20% de 2 Gb de memoria.
A pesar de esto el aspnet llega a 465mb sin reciclarse,  cuando deberia
llegar a 409mb nomas.
 
Lo voy a bajar al 18% y pruebo.
 
 
Gracias Fernando!
 
PD.: Felices fiestas! Que tengan un muy buen anio!
 
 

  _____  

De: [email protected] [mailto:[EMAIL PROTECTED] En nombre de Fernando
Tubio
Enviado el: Viernes, 29 de Diciembre de 2006 12:42 p.m.
Para: [email protected]
Asunto: [puntonet] Consulta sobre Process recycling de aspnet_wp.exe


Hola Pablo,
 
En realidad mi intención fue ilustrar que el 'process recycling' y el
OutOfMemoryException, aún cuando ambos se relacionan con el consumo de
memoria, son dos cosas distintas. El propósito de los ejemplos era el de
mostrar como se podía provocar cada uno de estos eventos sin que fuera
necesario que ocurriese el otro, pero de ninguna manera pretendía proponer
que estos eran los únicos mecanismos que los causaban.
 
 
..."Caso 1: donde pido toda la memoria junta que si no hay suficiente no se
recicla."...
FT: Esto es incorrecto. Cuando pedís toda la memoria junta, y no existe
suficiente memoria para satisfacer la asignación, se produce un
OutOfMemoryException, pero el proceso *NO* se recicla, aunque si puede
quedar en un estado inestable si no se toman las medidas necesarias. Esto
puede ocurrir como en el ejemplo, cuando se solicita una cantidad muy grande
de memoria, pero también podría suceder con una asignación mucho menor, si
no existiese suficiente memoria libre. Simplemente elegí en el ejemplo
solicitar un array de bytes muy grande por un tema de comodidad.
 
 
..."Caso 1:
Si yo tengo 78mb libres del sistema operativo, segun el contador Available
MB, para generar un OutOfMemory deberia estar llenando por lo menos 70Mb de
memoria en una sola linea de codigo. No desarrolle la aplicacion, pero no
creo que sea esa la situacion.
Por otro lado, cuando tira un OutOfMemopryException, despues veo requests
que nunca pueden consumir tanta memoria siguen tirando OutOfMemoryException.
Puede ser que el sistema operativo diga cuando me quedan 78Mb libres, al
aspnet_wp.exe no le doy un byte mas ?"...
FT: Aunque sea improbable que una única asignación corresponda a 70MB, hay
que tener en cuenta que si bien la aplicación puede estar solicitando 100
bytes, el administrador de memoria del runtime realiza solicitudes al
sistema operativo en bloques mucho más grandes (creo que 64MB) que luego
fracciona para satisfacer las necesidades de las aplicaciones. La memoria
solicitada no solo tiene que estar libre, sino que también debe existir en
un bloque continuo, de lo contrario se produce un OutOfMemoryException. A
medida que se solicita y libera memoria en un proceso, esta gradualmente se
fragmenta , y es muy posible que el bloque de memoria de 78MB que mencionás
no se encuentre todo en un mismo bloque, por lo tanto cuando el runtime
solicita 64MB no existe memoria suficiente. Para ilustrar con un caso un
tanto forzado, supongamos que la memoria total es de 2GB, y que se encuentra
totalmente libre excepto por bloques de 1MB cada 63MB de memoria asignada.
Es decir que salvo 32MB de memoria asignada todo el resto se encuentra
disponible. Cuando el runtime solicita un bloque de 64MB, si bien existe
casi 2GB (-32MB) libres, no existe un bloque de ese tamaño de memoria
continua y por lo tanto la asignación falla. 
 
Hay que destacar que todo lo que menciono ocurre a nivel del sistema
operativo. En el heap del runtime ocurren mecanismos similares pera la
diferencia es que el runtime es capaz de compactar la memoria y eliminar en
gran parte la fragmentación. Aún así, es también posible que la memoria del
runtime se fragmente, especialmente cuando se hacen llamados a código no
manejado, y cuando se fija la memoria mediante 'pinning'.
 
 
...Caso 2:
Me surge una duda, segun lo que comentas cuando vas pidiendo memoria en
etapas, se dispara el GC ... y si no puede liberar se recicla ... pero ese
request se va a seguir ejecutando en el mismo working process que se
origino, por lo tanto por mas que se recicle va a necesitar la memoria en
ese working process. Es asi o hace un traspaso de request de un working
process a otro ?...
FT: Esto tampoco es completamente correcto. El GC es un mecanismo inherente
a la gestión de memoria del runtime, mientras que el reciclado es una
característica de ASP.NET, y no una consecuencia directa del GC, sino mas
bien un mecanismo de protección contra fallas en las aplicaciones. El
reciclado ocurre cuando se supera un límite arbitrario de memoria, bajo la
presunción de que la aplicación no debería consumir más memoria que la
prevista por este límite y por lo tanto si esto ocurre es prudente reiniciar
la aplicación. El limíte establecido en <processModel> para el reciclado no
implica que una solicitud de memoria no tenga éxito. 
 
Supongamos que se configuró ASP.NET de tal forma que la aplicación sea
reciclada cuando supera el 60% de la memoria disponible, que la memoria
total es de 1GB, y que al comienzo de un request la memoria total asignada
es de 600MB (estoy simplificando 1GB === 1000MB). Si durante la ejecución de
solicitud se asigna memoria adicional, no es que esta será denegada y el
proceso se recicla inmediatamente, sino que la solicitud tendrá éxito y
finalizará normalmente. Sin embargo, el proceso habrá superado el límite
establecido e iniciará el reciclaje. Todas las solicitudes actualmente en
ejecución serán procesadas por el proceso que está siendo terminado,
mientras que cualquier solicitud nueva es atendida por un proceso nuevo que
se inicia.  Mientras las solicitudes en ejecución en el momento en que se
produce el reciclaje hagan pedidos de memoria 'razonables' - pensá que
todavía quedan 40% de memoria teóricamente disponible - entonces no hay
motivo por el cual no deberían finalizar normalmente.
 
Espero que ahora quede un poco más claro.
 
Saludos,
 
Fernando Tubio
 
----- Original Message ----- 

From: Pablo A. Allois <mailto:[EMAIL PROTECTED]>  
To: [email protected] 
Sent: Friday, December 29, 2006 10:52 AM
Subject: [puntonet] Consulta sobre Process recycling de aspnet_wp.exe


Bueno, entonces tenemos dos casos ... 
Caso 1: donde pido toda la memoria junta que si no hay suficiente no se
recicla.
Caso 2: donde voy pidiendo la memoria y si lo necesita puede reciclarse.
 
Caso 1:
Si yo tengo 78mb libres del sistema operativo, segun el contador Available
MB, para generar un OutOfMemory deberia estar llenando por lo menos 70Mb de
memoria en una sola linea de codigo. No desarrolle la aplicacion, pero no
creo que sea esa la situacion.
Por otro lado, cuando tira un OutOfMemopryException, despues veo requests
que nunca pueden consumir tanta memoria siguen tirando OutOfMemoryException.
Puede ser que el sistema operativo diga cuando me quedan 78Mb libres, al
aspnet_wp.exe no le doy un byte mas ?
 
 
Caso 2:
Me surge una duda, segun lo que comentas cuando vas pidiendo memoria en
etapas, se dispara el GC ... y si no puede liberar se recicla ... pero ese
request se va a seguir ejecutando en el mismo working process que se
origino, por lo tanto por mas que se recicle va a necesitar la memoria en
ese working process. Es asi o hace un traspaso de request de un working
process a otro ?
 
 
Gracias

  _____  

De: [email protected] [mailto:[EMAIL PROTECTED] En nombre de Fernando
Tubio
Enviado el: Jueves, 28 de Diciembre de 2006 02:50 p.m.
Para: [email protected]
Asunto: [puntonet] Consulta sobre Process recycling de aspnet_wp.exe


Son dos cosas diferentes. El proceso se recicla cuando la memoria utilizada
por el proceso aspnet_wp.exe supera un límite preestablecido. Un
OutOfMemoryException ocurre cuando una asignación de memoria falla debido a
que no existe suficiente memoria disponible para satisfacerla. Cualquiera de
estos eventos puede ocurrir sin la existencia del otro. Esto se puede ver
con un ejemplo sencillo. Crea un web form con dos botones, agregando los
siguientes handlers respectivamente.
 
protected void Button1_Click ( object sender, EventArgs e )
{
    byte [ ] buffer = new byte[ int.MaxValue ];
}
 
private static ArrayList _items = new ArrayList( 1000 );
 
protected void Button2_Click ( object sender, EventArgs e )
{
    for ( int i = 0; i < _items.Capacity; ++i )
    {
        _items.Add( new byte[ 1000000 ] );
    }
}
 
El primer botón asigna una cantidad de memoria que el sistema no puede
satisfacer y provoca un OutOfMemoryException. Sin embargo, como la memoria
nunca llega a ser asignada, el proceso continúa su ejecución. En el ejemplo
no agrego ningún tipo de manejo de errores, pero se podría agregar un catch
y atrapar el OutOfMemoryException. Por supuesto, dependerá de las
circunstancias si la aplicación puede recuperarse de este error. Cuando el
runtime no puede satisfacer una asignación de memoria, automáticamente
dispara un GC con la esperanza de liberar la memoria necesaria, que es lo
que estás observando.
 
El segundo botón asigna bloques de memoria que si bien individualmente
pueden ser satisfechos, eventualmente la memoria consumida eventualmente
supera el límite establecido en machine.config, y el proceso se recicla. Los
valores que elegí son suficientes para provocar esto en mi máquina de
desarrollo, pero pueden variar de acuerdo a la cantidad de memoria RAM y los
valores configurados en <processModel>.
 
 
Saludos,
 
Fernando Tubio

----- Original Message ----- 
From: Pablo A. Allois <mailto:[EMAIL PROTECTED]>  
To: [email protected] 
Sent: Thursday, December 28, 2006 10:44 AM
Subject: [puntonet] Consulta sobre Process recycling de aspnet_wp.exe

Buenos dias señores,
 
        La consulta viene a raiz de que tengo un servidor en el que corren
unos webservices en .net 1.0 que cuando llega a cierto punto de uso de
memoria dispara la exception Systtem.OutOfMemoryException.
 
        Ya configure el processmodel del machine.config para que el
aspnet_wp.exe se recicle ... pero cuando llega el momento en que se tiene
que reciclar sale con un outofmemory y no se recicla.
 
        La pregunta es ... que puede estar pasando que no permite que se
recicle el proceso ?
 
        El servidor es un windows 2000 server sp4 ... IIS 5.
        Corren aplicaciones .net y java.
        Tiene 2Gb de memoria.
 
 <processModel enable="true" timeout="Infinite"
            idleTimeout="1:00:00" shutdownTimeout="0:00:20" 
            requestLimit="Infinite" requestQueueLimit="5000" 
            restartQueueLimit="10" 
            memoryLimit="20" 
            webGarden="false" cpuMask="0xffffffff"
            userName="*****" password="******"
            logLevel="All" clientConnectedCheck="0:00:05"
            comAuthenticationLevel="Connect"
comImpersonationLevel="Impersonate"
            responseRestartDeadlockInterval="00:03:00"
responseDeadlockInterval="00:03:00" 
            maxWorkerThreads="100" maxIoThreads="100"
        />        
 
        Lo que noto es que al llegar al memorylimit el GC empieza a
trabajar, y luego de intentar liberar dispara la exception de out of memory.
 
        Si pueden ser utiles, tengo un log de performance para pasar.
 
 
Saludos!

Responder a