From: Brent Roman Date: 2008-11-13T17:33:05+09:00 Subject: [ruby-core:19913] Re: [Bug #744] memory leak in callcc? Roger, This "leak" appears to be an artifact of MRI's conservative garbage collector. Depending upon the compiler options and the target CPU, there may be unused references to these continuation objects left on the thread's stack when it is copied in whole to by the callcc method. In your example, these unused references form a linked list of continuations across the loop iterations. When the GC tries to mark such a recursive structure, it consumes a lot of stack space. With Ruby 1.68, this leads to a segmentation fault when the stack size exceeds the max allowed (see ulimit -s) With later versions of Ruby, the mark phase of the GC will "give up" when the stack grows too large. This avoids the segfault, as GC silently stops working instead. At least that's what I think I see in v1.8.7 p72 When I built x86 Ruby using gcc without optimization (CFLAGS=-g), even this caused a memory leak: loop { callcc {|c| c}} However, when I rebuilt it with CFLAGS=-O2, the memory leak only appeared when the continuations returned by callcc where assigned to a variable. When compiled for the ARM9 with gcc CFLAGS=-Os or CFLAGS=-O2, everything works as it should. No leaks observed. However, when I changed to CFLAGS=-g or CFLAGS=-O3, the original example leaks badly. These tests were performed using x86 gcc v3.3.5 and ARM gcc v3.4.5. Can anyone suggest debugging techniques to help determine what is leaving the dangling references to these continuations on Ruby's 'C' call stack? If we knew what wrote these, we might be able to explicitly clear them once they go out of scope. This should result in better significantly GC performance all around. - brent Brent Roman wrote: > > Roger, > > I've run into a number of issues related to Continuations and MRI's > garbage collector, > so I thought I'd have a look at this one. I investigated the equivalent > (non-generator) > example described at: > > http://rubyforge.org/tracker/?func=detail&atid=1698&aid=7896&group_id=426 > > This: > > loop {@x = callcc {|c| c}} > > quickly consumes all of memory. > > One of my x86 Linux machines crashed after a couple minutes of running > this > loop with a Segmentation Fault. My guess here is that the stack, which > during > GC is unchecked, got too deep. > > > > Roger Pack-5 wrote: >> >> Bug #744: memory leak in callcc? >> http://redmine.ruby-lang.org/issues/show/744 >> >> Author: Roger Pack >> Status: Open, Priority: Normal >> >> from >> http://rubyforge.org/tracker/?func=detail&atid=1698&aid=7896&group_id=426 >> this code >> require 'generator' >> loop { g = Generator.new {|x| (1..3).each {|i| x.yield i}} } >> >> seems to leak for me--I'm not sure if this is expected or not. >> >> Thanks. >> >> >> ---------------------------------------- >> http://redmine.ruby-lang.org >> >> >> > > -- View this message in context: http://www.nabble.com/-ruby-core%3A19846---Bug--744--memory-leak-in-callcc--tp20447794p20476661.html Sent from the ruby-core mailing list archive at Nabble.com.