From: Yohanes Santoso Date: 2005-10-16T16:02:26+09:00 Subject: Re: Help! define_method leaking procs... Eric Mahurin writes: >> 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. Be careful, 1. there is no evidence yet that ruby is not freeing every allocation, and 2. I am not saying there is no memory leak caused by define_method. What I have been saying is, you can't use VmSize as an indicator of memory leak. I have shown examples where the order of free() can affect VmSize. Here is an alternative scenario that would have resulted in what you are seeing: ruby could have free()-ed all its allocations properly when you call GC.start, but may free() them in different order on each test case which result in you seeing different VmSize values. Probably that is not what happens; Probably there really is a genuine memory leak; But you can't determine which scenario is happening from VmSize value. > 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. This only shows whether the free-ing is done immediately or not. Thus, why my example program focuses in the immediateness of freeing. > 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. Memory leak is tricky to show since it requires one to prove that there is an allocation that is not free-ed by the time the process ends. However, there are evidences (search the archive for GC problems) that the GC is too conservative (read: lazy) and stupid in some cases. Sometimes, you need to drop the clue book on its head, like doing a=nil. Without the a=nil, the number of objects is not decreased by much after GC. > The point is you better be careful with closures (block/lambda) Yes, be careful as the GC is a lazy bum. In any case, here is another 'fixed' version. ysantoso@jenny:/tmp$ ruby -e 'n=2**13;for i in (1..n) do a=(1..i).to_a;self.class.send(:define_method,:"f#{i}"){i*i} end;GC.start; IO.readlines("/proc/#{Process.pid}/status").grep(/VmSize/).display' VmSize: 11268 kB YS.