From: Rick DeNatale Date: 2008-01-10T08:04:12+09:00 Subject: Re: why does this code leak? On Jan 9, 2008 5:18 PM, ara howard wrote: > > On Jan 9, 2008, at 2:52 PM, Rick DeNatale wrote: > > > Looking at eval.c, it looks like lambda actually copies information > > from the invocation stack, not just from the current frame. In the > > leaky finalizer case we have the following on the stack when > > leaky_finalizer is called, with the binding represented in hash > > notation. > > > > leaky_finalizer :self => Class > > finalizer :self => Class > > new :self=> Class, :object => the new Array > > instance > > code which called Array.new > > > > The leak free finalizer lambda was created once at a time when no > > instance to be finalized was on the stack. > > yeah i think that may be true - but it doesn't make sense. the > > def leaky_finalizer > lambda{} > end > > is the current paradigm for preventing lambdas from enclosing a > reference to an object. what you are saying is that this call > encloses a local variable from another (the calling in the this case) > function. Well I'm positing that based on a rather superficial read of eval.c. > how would that not be a bug? why enclose a variable that cannot > possible be reached in the code ran? Well I suspect that it's because no real analysis is done of what's inside the block when a proc is created, so the assumption is that the entire binding is needed. The Smalltalk compilers I recall would produce different types of block objects depending on whether or not the block contained references to variables outside the block, and/or contained a return. Now why it goes back down the stack, if it indeed does, I'm not sure. Perhaps it has something to do with the lambda vs. Proc.new differences. I think that Proc.new and lambda/proc both use the proc_alloc function where this seems to be happening. In any event this is probably more a topic for ruby-core so I'm cross-posting this reply there. > this seems, to me just like this > code > > void * leak (){ return(&malloc(42)) } > > i just cannot image why lambda would crawl up the stack outside the > current function. if that is true then they are useless and *any* > invocation means every object in memory at the time of creation can > never be freed while that lambda exists. doesn't that seem > excessive? also i use tons of lambdas in code that does not leak so > this just seems impossible. > > nevertheless you may be right! Or not -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/