From: Eric Mahurin Date: 2005-10-16T14:27:57+09:00 Subject: Re: Help! define_method leaking procs... --- Yohanes Santoso wrote: > Eric Mahurin writes: > > > --- Yohanes Santoso > > > wrote: > > > >> Eric Mahurin writes: > >> > >> > n=2**13;(1..n).each{|i| > >> > > >> > > > a=(1..i).to_a;self.class.send(:define_method,:"f#{i}"){i*i}};GC.start; > >> > > >> > > > IO.readlines("/proc/#{Process.pid}/status").grep(/VmSize/).display' > >> > VmSize: 172028 kB > >> > >> > ruby -e ' > >> > n=2**13;(1..n).each{|i| > >> > > >> > > > a=(1..i).to_a;self.class.send(:define_method,:"f#{i}"){i*i};a=nil};GC.start; > >> > > >> > > > IO.readlines("/proc/#{Process.pid}/status").grep(/VmSize/).display' > >> > VmSize: 11504 kB > >> > >> Stop right there. I want to remind people that you can't > use > >> VmSize as > >> a leak indicator. In some OS, VmSize is an always > increasing > >> number. Memory allocated in a process is not returned to > the > >> OS until > >> the process dies. > > > > OK. Pick another way to measure memory. top shows the > same > > memory as above for me. Or make n=2**15. This brings my > > machine (768MB) to its knees: > > > > ruby -e 'n=2**15;(1..n).each{|i| > > > a=(1..i).to_a;self.class.send(:define_method,:"f#{i}"){i*i}};GC.start; > > > IO.readlines("/proc/#{Process.pid}/status").grep(/VmSize/).display' > > > > I'd estimate it would use about 3GB. And if you put an > a=nil > > after the define_method, you get this: > > > > ruby -e 'n=2**15;(1..n).each{|i| > > > a=(1..i).to_a;self.class.send(:define_method,:"f#{i}"){i*i};a=nil};GC.start; > > > IO.readlines("/proc/#{Process.pid}/status").grep(/VmSize/).display' > > VmSize: 31032 kB > > > That is still not a valid way to detect leak as that still > depends on > VmSize value. Ruby could be freeing every allocation and the > Vmsize > would still grow. But it is not. Have you tried this example? On my 768MB machine, top shows it filling my physical memory and then the the CPU drops to about 3% because it starts swapping and my machine becomes very unresponsive. I'd say that's a good indication that top is reporting the right thing. You could consider this case a bug in ruby or a bug in the simple test case above. It doesn't matter where the fault lies, it still shows a memory leak. The point is you better be careful with closures (block/lambda) because they carry all the variables in scope in Proc#binding in the current implementation. Personally, I would like to see something done about this in ruby, but at minimum people need to be aware of this memory issue (as ruby stands now). __________________________________ Yahoo! Mail - PC Magazine Editors' Choice 2005 http://mail.yahoo.com