Ruby Forum Rails-ES > Memory Leaks

Posted by Isaac Feliu Pérez (Guest)
on 19.08.2008 02:39
(Received via mailing list)
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,
Posted by Andrés Gutiérrez (andresgutgon)
on 19.08.2008 09:41
(Received via mailing list)
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 <isaac.feliu@gmail.com>
Posted by Xavier Noria (fxn)
on 19.08.2008 12:55
(Received via mailing list)
2008/8/19 Andrés gutiérrez <andresgutgon@gmail.com>:

> 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

   http://blog.pluron.com/2008/01/ruby-on-rails-i.html
Posted by Isaac Feliu Pérez (Guest)
on 19.08.2008 13:03
(Received via mailing list)
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
Posted by Daniel Rodriguez Troitiño (Guest)
on 19.08.2008 13:07
(Received via mailing list)
2008/8/19 Xavier Noria <fxn@hashref.com>:
> 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
>
>   http://blog.pluron.com/2008/01/ruby-on-rails-i.html

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.
Posted by Ruben Davila (rdavila)
on 19.08.2008 16:20
(Received via mailing list)
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 ;)

Saludos.