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,
on 19.08.2008 02:39
on 19.08.2008 09:41
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>
on 19.08.2008 12:55
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
on 19.08.2008 13:03
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
on 19.08.2008 13:07
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.
on 19.08.2008 16:20
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.