# GC and Threads

**URL:** <https://www.ruby-forum.com/t/gc-and-threads/160017>\
**Category:** Ruby\
**Created:** [February 10, 2009, 11:53pm UTC](https://www.ruby-forum.com/t/gc-and-threads/160017 "2009-02-10T23:53:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bbazzarrakk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/47e85d/32.png) [@bbazzarrakk](https://www.ruby-forum.com/u/bbazzarrakk)\
**Post date:** [February 10, 2009, 11:53pm UTC](https://www.ruby-forum.com/t/gc-and-threads/160017/1 "2009-02-10T23:53:05Z")

</div>

I’m trying to prove two simple facts about how Ruby works:

- Ruby can GC a Thread that has run to completion if you no longer  
have any references to it, even if the value() have never been collected
- Ruby cannot GC a running Thread, even if there are no references to it

Some new code I have relies on these truths. Simple scripts I’ve  
written seems to indicate they are accurate, but I would love to hear  
from someone who knows these to be true, or untrue.

Thanks in advance for any information you can provide.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![bbazzarrakk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/47e85d/32.png) [@bbazzarrakk](https://www.ruby-forum.com/u/bbazzarrakk)\
**Post date:** [February 11, 2009, 12:00am UTC](https://www.ruby-forum.com/t/gc-and-threads/160017/2 "2009-02-11T00:00:06Z")

</div>

On Feb 10, 2009, at 4:51 PM, James G. wrote:

> I’m trying to prove two simple facts about how Ruby works:
> 
> - Ruby can GC a Thread that has run to completion if you no longer  
> have any references to it, even if the value() have never been  
> collected
> - Ruby cannot GC a running Thread, even if there are no references  
> to it

> Simple scripts I’ve written seems to indicate they are accurate…

Actually, this is difficult to judge. For example, this script has  
odd results on my machine. The Thread count does drop, but not all  
the way:

#!/usr/bin/env ruby -wKU

def show\_thread\_count  
count = 0  
ObjectSpace.each\_object(Thread) { |obj| count += 1 }  
p count  
end

show\_thread\_count

5.times do  
Thread.new do  
date = `sleep 1 && date`  
end  
end

20.times do  
sleep 0.2

3.times { GC.start }  
show\_thread\_count  
end

**END**

Here’s a pretty typical output, though it varies a little:

$ ruby testing\_thread\_gc.rb  
1  
6  
6  
6  
6  
3  
3  
3  
3  
3  
3  
3  
3  
3  
3  
3  
3  
3  
3  
3  
3

Thoughts?

James Edward G. II

---

<div class="post-metadata">

**Author:** ![bbazzarrakk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/47e85d/32.png) [@bbazzarrakk](https://www.ruby-forum.com/u/bbazzarrakk)\
**Post date:** [February 11, 2009, 12:53am UTC](https://www.ruby-forum.com/t/gc-and-threads/160017/3 "2009-02-11T00:53:21Z")

</div>

James G. wrote:

> def show\_thread\_count  
> count = 0  
> ObjectSpace.each\_object(Thread) { |obj| count += 1 }  
> p count  
> end

Btw, this is the same as

def show\_thread\_count  
p ObjectSpace.each\_object(Thread) {}  
end

---

<div class="post-metadata">

**Author:** ![bbazzarrakk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/47e85d/32.png) [@bbazzarrakk](https://www.ruby-forum.com/u/bbazzarrakk)\
**Post date:** [February 11, 2009, 1:26am UTC](https://www.ruby-forum.com/t/gc-and-threads/160017/4 "2009-02-11T01:26:42Z")

</div>

James G. wrote:

> - Ruby can GC a Thread that has run to completion if you no longer  
> have any references to it, even if the value() have never been collected

Not sure.

> - Ruby cannot GC a running Thread, even if there are no references to it

Unfortunately, this part is true, as Ruby has not solved the Halting  
Problem.

It might be possible to collect a thread if you have very specific  
knowledge about when it is no longer needed. The hack I’ve been playing  
with lately is to have all access to the thread be through a specific  
object or set of objects, and reap the thread in the finalizer(s) of  
those object(s).

The part I haven’t solved is circular references – anything one thread  
has a reference to can’t be collected as long as that thread is running,  
so if thread A knows about thread B, which also knows about thread A,  
they will have to be manually cleaned, even if that knowledge is purely  
through such proxy objects.

Oh – the above rambling might make sense in context. I’m writing an  
actor library. I can picture a state where a collection of actors should  
be collected, as they’re all out of messages and only referred to by  
each other – but while I theoretically should be able to write a  
garbage collector for that, I can’t figure out how to do it in Ruby  
without at least writing a C extension.

---

<div class="post-metadata">

**Author:** ![bbazzarrakk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/47e85d/32.png) [@bbazzarrakk](https://www.ruby-forum.com/u/bbazzarrakk)\
**Post date:** [February 11, 2009, 1:56am UTC](https://www.ruby-forum.com/t/gc-and-threads/160017/5 "2009-02-11T01:56:33Z")

</div>

On Feb 10, 2009, at 6:25 PM, David M. wrote:

> James G. wrote:
> 
> > - Ruby can GC a Thread that has run to completion if you no longer  
> > have any references to it, even if the value() have never been  
> > collected
> 
> Not sure.

It seems this is at least somewhat true. See the script I posted  
earlier in this thread for an example. I would love to know why it  
can’t totally clear them in that example though.

> > - Ruby cannot GC a running Thread, even if there are no references  
> > to it
> 
> Unfortunately, this part is true, as Ruby has not solved the Halting  
> Problem.

Well, it happens to help me in this case, so I’ll call it a bonus. 🙂

James Edward G. II
