From: Robert Klemme Date: 2008-09-18T00:36:59+09:00 Subject: Re: Threads preventing garbage collection? 2008/9/17 ara.t.howard : > > On Sep 17, 2008, at 8:49 AM, Brian Candler wrote: > >> Your version only works because the threads are dying after 2 seconds. >> Change >> >> def make_thread >> Thread.new { sleep 2 } >> end >> >> to >> >> def make_thread >> Thread.new { sleep 10000 } >> end >> >> and run it again. Good point! > but that it expected? you have a Foo which referes to a Thread which has > not died that is itself referred to by the global Thread.list Yeah, but there is no reference back to the Foos so they could be collected. If you change the code to def make_thread Thread.new { loop { sleep 2 } } end ... 1000.times { Foo.new.bar = "x" * rand(100) # make_thread } Then Foo instances are quickly removed although 1 is still referenced. The only explanation I have ATM is that the thread stack might be copied somehow and thus keep the ref alive. Interesting enough ruby19 behaves much differently: the count goes down to 0 instead of 1. But with the old version (i.e. Foo.new.bar = make_thread) I get thread creation errors. With some changing the number actually goes down to 0: 17:43:31 Temp$ cat gc.rb def make_thread Thread.new { loop { sleep 2 } } # Thread.new { loop { Array.new(1_000_000); sleep 0.1 } } end class Module def count c = 0 ObjectSpace.each_object(self) { c += 1 } c end end Foo = Struct.new :bar 10.times { # Foo.new.bar = "x" * rand(100) Foo.new.bar = make_thread } puts "Threads created" # use memory Thread.new { loop { Array.new(1_000_000); sleep 0.1 } } loop do puts Foo.count GC.start sleep 1 end 17:43:37 Temp$ ruby19 --version ruby 1.9.0 (2008-03-01 revision 15664) [i386-cygwin] 17:43:48 Temp$ ruby19 gc.rb Threads created 10 0 0 0 0 0 0 0 0 0 17:44:01 Temp$ Kind regards robert -- use.inject do |as, often| as.you_can - without end