<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comentarios en: Ruby/Rails y sus cositas&#8230;</title>
	<atom:link href="http://www.isaacfeliu.com/2008/08/rubyrails-y-sus-cositas/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.isaacfeliu.com/2008/08/rubyrails-y-sus-cositas/</link>
	<description>Blog de Isaac Feliu, Emprendedor</description>
	<pubDate>Tue, 06 Jan 2009 19:47:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
		<item>
		<title>Por: Macbook Pro &#9830; Apple MacBook and MacBook Pro News</title>
		<link>http://www.isaacfeliu.com/2008/08/rubyrails-y-sus-cositas/#comment-103</link>
		<dc:creator>Macbook Pro &#9830; Apple MacBook and MacBook Pro News</dc:creator>
		<pubDate>Fri, 17 Oct 2008 23:15:12 +0000</pubDate>
		<guid isPermaLink="false">http://www.isaacfeliu.com/?p=33#comment-103</guid>
		<description>&lt;strong&gt;Ruby/Rails y sus cositas... - Macbook Pro &#9830; Apple MacBook and MacBook Pro News...&lt;/strong&gt;

[...] an interesting post was made today on this site [...]......</description>
		<content:encoded><![CDATA[<p><strong>Ruby/Rails y sus cositas&#8230; - Macbook Pro &diams; Apple MacBook and MacBook Pro News&#8230;</strong></p>
<p>[...] an interesting post was made today on this site [...]&#8230;&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: YoNoSoyTu</title>
		<link>http://www.isaacfeliu.com/2008/08/rubyrails-y-sus-cositas/#comment-76</link>
		<dc:creator>YoNoSoyTu</dc:creator>
		<pubDate>Tue, 19 Aug 2008 10:59:59 +0000</pubDate>
		<guid isPermaLink="false">http://www.isaacfeliu.com/?p=33#comment-76</guid>
		<description>Opino igual que Xavier, no es un memory leak como tal: los callbacks deben devolver un valor, y en tu caso devuelves el array (cada vez más grande) de usuarios que están en la "discussion", probando a devolver simplemente nil o false funciona sin problemas. Si no devuelvo false o nil la memoria empieza a crecer un mega cada par de segundos.

Viendo el código y sin conocer exactamente la gestión de memoria de Ruby y su recolector de basura voy a hechar la culpa a los closures que se generan durante la ejecución de los callbacks. Estoy pensando que, de alguna forma, los closures que se van formando en cada iteración se mantienen en scope, y el GC no los elimina, con lo que se queda un closure con 1 usuario, otro con 2, otro con 3, etcétera... al de las iteraciones tenemos unos 450.000 objetos User en memoria. No se cuanto ocupan en memoria un objeto ActiveRecord, pero 450.000 objetos son muchos objetos.

Creo que la moraleja es siempre devolver true o false en lo callbacks (true, false y nil deben ser valores compartidos en Ruby, por lo que no deben aumentar tanto el uso de memoria).</description>
		<content:encoded><![CDATA[<p>Opino igual que Xavier, no es un memory leak como tal: los callbacks deben devolver un valor, y en tu caso devuelves el array (cada vez más grande) de usuarios que están en la &#8220;discussion&#8221;, probando a devolver simplemente nil o false funciona sin problemas. Si no devuelvo false o nil la memoria empieza a crecer un mega cada par de segundos.</p>
<p>Viendo el código y sin conocer exactamente la gestión de memoria de Ruby y su recolector de basura voy a hechar la culpa a los closures que se generan durante la ejecución de los callbacks. Estoy pensando que, de alguna forma, los closures que se van formando en cada iteración se mantienen en scope, y el GC no los elimina, con lo que se queda un closure con 1 usuario, otro con 2, otro con 3, etcétera&#8230; al de las iteraciones tenemos unos 450.000 objetos User en memoria. No se cuanto ocupan en memoria un objeto ActiveRecord, pero 450.000 objetos son muchos objetos.</p>
<p>Creo que la moraleja es siempre devolver true o false en lo callbacks (true, false y nil deben ser valores compartidos en Ruby, por lo que no deben aumentar tanto el uso de memoria).</p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: isaac</title>
		<link>http://www.isaacfeliu.com/2008/08/rubyrails-y-sus-cositas/#comment-75</link>
		<dc:creator>isaac</dc:creator>
		<pubDate>Tue, 19 Aug 2008 09:58:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.isaacfeliu.com/?p=33#comment-75</guid>
		<description>Razón llevas Xavier,

a esas horas de la madrugada uno ya no estaba demasiado fino como para ponerse a probar cosas, a ver si saco algo de tiempo esta semana y veo en más profundidad que está pasando, tal vez pueda caer algun parche...

Encantado de tenerte por aqui!</description>
		<content:encoded><![CDATA[<p>Razón llevas Xavier,</p>
<p>a esas horas de la madrugada uno ya no estaba demasiado fino como para ponerse a probar cosas, a ver si saco algo de tiempo esta semana y veo en más profundidad que está pasando, tal vez pueda caer algun parche&#8230;</p>
<p>Encantado de tenerte por aqui!</p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Xavier Noria</title>
		<link>http://www.isaacfeliu.com/2008/08/rubyrails-y-sus-cositas/#comment-74</link>
		<dc:creator>Xavier Noria</dc:creator>
		<pubDate>Tue, 19 Aug 2008 01:46:10 +0000</pubDate>
		<guid isPermaLink="false">http://www.isaacfeliu.com/?p=33#comment-74</guid>
		<description>Bueno saberlo!

Creo de todos modos que el porqué es otro, me explico.

Este programa

def build_large_array
  Array.new(5000)
end

while true
  build_large_array
end

no tiene un leak. La memoria sube hasta que entra el garbage collector (a los 7-8 megas en mis pruebas). Si asignas el array a una variable que luego nilificas el comportamiento es el mismo.

A posteriori dirias que la asignacion no afecta porque igualmente sucede que el array es un objeto que es susceptible de ser recolectado porque fue creado. Es decir, que la variable que lo almacenaba apunte a otra cosa lo hace recolectable del mismo modo que lo hace el que no este almacenado en ninguna variable ya de entrada.

Dicho esto, he replicado tus modelos y en mi maquina pasa lo mismo. Pero parece que depende del valor _retornado_ por el hook mas que de nilificar una variable, ya que evitamos el leak tambien si hacemos simplemente esto:

(group.discussion.users &#60;&#60; user) &#38;&#38; true

Mi conjetura es que el valor retornado por el callback se esta quedando almacenado en algun lugar de AR y no puede recolectarse.</description>
		<content:encoded><![CDATA[<p>Bueno saberlo!</p>
<p>Creo de todos modos que el porqué es otro, me explico.</p>
<p>Este programa</p>
<p>def build_large_array<br />
  Array.new(5000)<br />
end</p>
<p>while true<br />
  build_large_array<br />
end</p>
<p>no tiene un leak. La memoria sube hasta que entra el garbage collector (a los 7-8 megas en mis pruebas). Si asignas el array a una variable que luego nilificas el comportamiento es el mismo.</p>
<p>A posteriori dirias que la asignacion no afecta porque igualmente sucede que el array es un objeto que es susceptible de ser recolectado porque fue creado. Es decir, que la variable que lo almacenaba apunte a otra cosa lo hace recolectable del mismo modo que lo hace el que no este almacenado en ninguna variable ya de entrada.</p>
<p>Dicho esto, he replicado tus modelos y en mi maquina pasa lo mismo. Pero parece que depende del valor _retornado_ por el hook mas que de nilificar una variable, ya que evitamos el leak tambien si hacemos simplemente esto:</p>
<p>(group.discussion.users &lt;&lt; user) &amp;&amp; true</p>
<p>Mi conjetura es que el valor retornado por el callback se esta quedando almacenado en algun lugar de AR y no puede recolectarse.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
