Memory Leaks

Buenas Lista,

Hoy me he topado con un memory leak como la copa de un pino, pero de
los altos. Simplemente queria compartirlo con vosotros para que os
suene el caso si algún dia teneis el mismo problema, y sepais como
solucionarlo.

La duda que tengo es si esto se podria considerar un bug de ruby, de
rails, mio, o… ¿? A estas horas uno ya no está demasiado fino…

Bueno, al trapo, para no repetir la historia, os paso el link a mi
blog, donde lo he posteado con un pequeño ejemplo. Si a alguien le
interesa investigar un poco, os puedo proporcionar el código de
ejemplo funcionando donde se puede comprobar “in person” lo que pasa.

http://www.isaacfeliu.com/2008/08/rubyrails-y-sus-cositas/

Si teneis dudas ya sabeis donde estoy!

Salutaciones,

Muchas gracias Issac por explicar las cosas tan claras. Yo no tengo
mucha
idea de programar ( y no sé si tienes toda la razón) , pero lo que tu
has
explicado me ha quedado claro y esto ya no me pasará.

Un saludo

2008/8/19 Isaac Feliu Pérez [email protected]

2008/8/19 Andrés gutiérrez [email protected]:

Muchas gracias Issac por explicar las cosas tan claras. Yo no tengo mucha
idea de programar ( y no sé si tienes toda la razón) , pero lo que tu has
explicado me ha quedado claro y esto ya no me pasará.

Envie un analisis como comentario.

El resumen seria que pienso que el problema radica en lo que
devuelve el hook. Parece a posteriori que se queda en AR y el
garbage collector no puede liberarlo. Como las sucesivas llamadas a <<
devuelven colecciones de usuarios en cada iteracion, van acumulando en
memoria

1 + 2 + … + 3000 = 4501500

objetos. Por eso en el ejemplo el leak canta malamente.

Lo de nilificar una variable creo que es una pista falsa. Soluciona el
problema, pero me parece que es porque el valor de retorno del hook es
el de la expresion “x = nil” que es nil. No tiene que ver con la
variable en si, tambien se soluciona con

(group.discussion.users << user) && true

que devuelve true. La coleccion es eventualmente recolectada y no hay
leak.

Los del patch de mejora del garbage collector comentaron algo acerca
de las asociaciones que podria tener alguna relacion, buscar
“HasAndBelongsToManyAssociation” en

Garbage Collection is Why Ruby on Rails is Slow: Patches to Improve Performance 5x; Memory Profiling - Acunote Blog

Xavier,

justo ayer buscando que carajo me estaba pasando di con este post del
blog, y me frustó el ver que no sabian que estaba pasando.

Como bien apuntas, el problema es por lo que retorna el callback. A
ver si tengo algo de tiempo e investigo más sobre el asunto…

Salutaciones,

Isaac Feliu

2008/8/19 Xavier N. [email protected]:

garbage collector no puede liberarlo. Como las sucesivas llamadas a <<
variable en si, tambien se soluciona con

(group.discussion.users << user) && true

que devuelve true. La coleccion es eventualmente recolectada y no hay leak.

Los del patch de mejora del garbage collector comentaron algo acerca
de las asociaciones que podria tener alguna relacion, buscar
“HasAndBelongsToManyAssociation” en

Garbage Collection is Why Ruby on Rails is Slow: Patches to Improve Performance 5x; Memory Profiling - Acunote Blog

Acabo de hacer unos cálculos similares y lo he dejado como comentario
(awaiting moderation) en el blog de Isaac, y llego a la misma
conclusión: no es un memory leak como tal sino que Ruby mantiene en
scope a todos esos objetos (mi suposición es como estado en los
closures que se crean) posiblemente a través de “g” o de “User.all” y
no los liberará hasta el final (habría que hacer pruebas con 500
objetos y ver si al final se libera la memoria).

Como conclusión: siempre debemos devolver true o false en los
callbacks, de forma que no se creen estos agujeros de memoria.

Si mal no recuerdo, mucho cuidado con devolver false en los callback
before_*, esto dara como resultado que el registro no sea grabado, fue
una
de las tantas malas noches que pase :wink:

Saludos.