Un aplauso de mi parte para esta respuesta :-).
 
Gracias Fernando
 
Carlos


  _____  

From: puntonet@mug.org.ar [mailto:[EMAIL PROTECTED] On Behalf Of Fernando
Tubio
Sent: Viernes, 29 de Diciembre de 2006 12:42 p.m.
To: puntonet@mug.org.ar
Subject: !-> [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: puntonet@mug.org.ar 
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

Responder a