# Ruby garabage collector

**URL:** <https://www.ruby-forum.com/t/ruby-garabage-collector/191508>\
**Category:** Ruby\
**Created:** [July 13, 2010, 5:30pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508 "2010-07-13T17:30:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 5:30pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/1 "2010-07-13T17:30:49Z")

</div>

In the “Why’s poignant guide to Ruby” book, it states the following:

“If you can’t get to an object through a variable, then Ruby will figure  
you are done with it and will get rid of it. Periodically, Ruby sends  
out its garbage collector to set these objects free.”

The point I’m not getting here is: “If you can’t get to an object  
through a variable…”

Can you provide an examples that illustrates this?

Thanks.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 5:36pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/2 "2010-07-13T17:36:25Z")

</div>

The simplest way to think of it is if something falls out of scope.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 5:42pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/3 "2010-07-13T17:42:04Z")

</div>

James H.on wrote:

> The simplest way to think of it is if something falls out of scope.

Thanks James. Can you provide a simple Ruby code to clarify the idea. A  
bit confusing me still.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 5:53pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/4 "2010-07-13T17:53:59Z")

</div>

On Jul 13, 2010, at 9:42 AM 7/13/10, Abder-Rahman A. wrote:

> James H.on wrote:
> 
> > The simplest way to think of it is if something falls out of scope.
> 
> Thanks James. Can you provide a simple Ruby code to clarify the idea. A  
> bit confusing me still.

Sure thing. Sounds like you might be new to programming, yeah? Scope is  
something you may need to look up to understand a little better. In ruby  
there are a few scope rules that you should look up and get familiar  
with, and they changed for 1.9.1 in some small ways (I believe…). The  
MetaProgramming Ruby book has some great insights into scope, too.

Simple, here’s an example:

words = [“foo”, “bam”, “bat”]

words.each do |word| #here we create a variable called “word”  
puts “#{word}” #here we print out the contents of the “word” variable  
end #here we end the block that word was created inside of

puts “#{word}” #this will fail, as word does not exist outside of the  
block

word is a variable that is local to the block associated with the .each  
call on the array. Once the block ends, the variable word stops  
existing: it “falls out of scope”.

Go read up on scoping and scope generally, it’ll do you good 😉

Best

James

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 5:59pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/5 "2010-07-13T17:59:53Z")

</div>

Bruno Antunes wrote:

> On 13-07-2010 17:30, Abder-Rahman A. wrote:
> 
> > Thanks.
> 
> a = [1,2,3].find {|x| x \> 3}
> 
> puts a
> 
> In this (maybe too simple) example, x is garbage-collected once flow  
> leaves the block.

Thanks Bruno.

But, I’m always getting as output:  
1  
2  
3

Even if I type {|x| x \< 3}

Isn’t your program trying to say find the values \> 3 ?

In other words, why don’t I get some sort of error since I’m requesting  
something not here? \> 3

Thanks.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 5:44pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/6 "2010-07-13T17:44:02Z")

</div>

On 13-07-2010 17:30, Abder-Rahman A. wrote:

> Thanks.

a = [1,2,3].find {|x| x \> 3}

puts a

In this (maybe too simple) example, x is garbage-collected once flow  
leaves the block.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 6:06pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/7 "2010-07-13T18:06:50Z")

</div>

Thanks a lot James for your clarification.

Actually, I;m familiar with scoping as I dealt with it in Java, and new  
to Ruby, and my point was the garbage collection here.

So, can I say that “word” in puts “#{word}” after the do-block is  
garbage collected since I know more have access to it?

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 6:14pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/8 "2010-07-13T18:14:29Z")

</div>

On Jul 13, 2010, at 9:59 AM 7/13/10, Abder-Rahman A. wrote:

> > In this (maybe too simple) example, x is garbage-collected once flow
> 
> Isn’t your program trying to say find the values \> 3 ?
> 
> In other words, why don’t I get some sort of error since I’m requesting  
> something not here? \> 3
> 
> Thanks

The point of the example is that x doesn’t exist any more outside of the  
block.

The array correctly returns the output “nil”, as no values inside the  
array are greater than 3. I’m not sure what you’re doing wrong: probably  
a typo somewhere.

metatron:~ james$ irb

> > a = [1,2,3].find {|x| x \> 3}  
> > =\> nil
> 
> > puts a  
> > nil  
> > =\> nil
> 
> > puts x  
> > NameError: undefined local variable or method `x’ for main:Object  
> > from (irb):3

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 6:16pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/9 "2010-07-13T18:16:15Z")

</div>

On Jul 13, 2010, at 10:06 AM 7/13/10, Abder-Rahman A. wrote:

> Thanks a lot James for your clarification.
> 
> Actually, I;m familiar with scoping as I dealt with it in Java, and new  
> to Ruby, and my point was the garbage collection here.
> 
> ## So, can I say that “word” in puts “#{word}” after the do-block is garbage collected since I know more have access to it?
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

Java’s garbage collected, too. So it’s just the same as in there. I  
imagine you’ve missed a central feature of Java somewhere 😉

The simple difference between garbage collection and  
non-garbage-collection is what happens when something falls out of  
scope. In C++, C, other languages that have manual memory management  
only, you have to free up the RAM assigned to the variable. In Java,  
Ruby, Python, Perl, those languages, the variable falls out of scope and  
the interpreter or compiler automatically frees the memory up for you.

Go read up on garbage collection.  
[Garbage collection (computer science) - Wikipedia](http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) isn’t  
atrocious, but maybe pick up a cheap computer science textbook or  
something.

The relationship you’re proposing is essentially correct, though. You no  
longer have access to “word”, so it’s garbage collected. The memory  
associated with it is freed up and your computer goes on living its  
quiet, binary life, sadly contemplating a time when its memory was full  
of ones and zeroes in orderly, useful fashion.

Best

James

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 6:18pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/10 "2010-07-13T18:18:59Z")

</div>

Thanks James.

It didn’t work me when I wrote your script as follows:

a = [1, 2, 3]  
a.find {|x| x \> 3}  
puts a  
puts x

Why doesn’t that give the same output as in the format written by you,  
while I can see that the logic here is correct?

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 6:24pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/11 "2010-07-13T18:24:34Z")

</div>

Thanks a lot James for your advice. Yes, think have to read more deeply  
about garbage collection.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 6:37pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/12 "2010-07-13T18:37:21Z")

</div>

On Tue, Jul 13, 2010 at 11:24 AM, Abder-Rahman A.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks a lot James for your advice. Yes, think have to read more deeply  
> about garbage collection.

This looks like the perfect opportunity to send this conversation way  
into technical land.

Consider the following presentation and then GC system:  
Joe Damato does a great job explaining GC under Ruby.  
[http://timetobleed.com/garbage-collection-and-the-ruby-heap-from-railsconf/](http://timetobleed.com/garbage-collection-and-the-ruby-heap-from-railsconf/)

I have also been reading up on a GC system called Schism- a real-time,  
concurrent non-moving, non-copying GC for java. I contacted the  
university listed as being a collaborate on this Schism. Sadly it is  
proprietary.  
However, if I could ever free up some time, I was going to check how  
patent encumbered it is. If the road is clear, then this would be a  
great thing to have in ruby.  
[www.filpizlo.com/slides/pizlo-pldi2010-schism-slides.pdf](http://www.filpizlo.com/slides/pizlo-pldi2010-schism-slides.pdf)

For those who don’t know, GC is often blamed- generally rightly so-  
for the biggest reason why ruby is slow.

I have no affiliate with either of these links.

Andrew McElroy

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 6:42pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/13 "2010-07-13T18:42:54Z")

</div>

Thanks Andrew. Helpful…

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 7:07pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/14 "2010-07-13T19:07:48Z")

</div>

On Tue, Jul 13, 2010 at 7:42 PM, Abder-Rahman A. \<  
removed\_email\_address@domain.invalid\> wrote:

> ## Thanks Andrew. Helpful…
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

Joe Damato did a good talk on this subject recently:

[http://blog.envylabs.com/2010/07/garbage-collection-the-ruby-heap/](http://blog.envylabs.com/2010/07/garbage-collection-the-ruby-heap/)

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 8:20pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/15 "2010-07-13T20:20:25Z")

</div>

I also wrote an article a while back on MRI’s memory allocation:

[http://www.engineyard.com/blog/2010/mri-memory-allocation-a-primer-for-developers/](http://www.engineyard.com/blog/2010/mri-memory-allocation-a-primer-for-developers/)

Kirk H.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 8:19pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/16 "2010-07-13T20:19:14Z")

</div>

On Tue, Jul 13, 2010 at 11:40 AM, Bruno A [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > Can you provide an examples that illustrates this?

Actually this is a bad example for several reasons.

1. variables don’t get collected, object do.  
[http://talklikeaduck.denhaven2.com/2006/09/13/on-variables-values-and-objects](http://talklikeaduck.denhaven2.com/2006/09/13/on-variables-values-and-objects)

In this example x is a variable which over the course of execution  
gets assigned to reference 1, then 2, then 3.

1. FixNums which are the only class of object assigned to x in this  
example are never garbage collected, since they are immediate values.

Now what does GC really do? What it really does is make sure that any  
object which can still be reached via a chain of references starting  
with a root set of references WON"T be freed and reused before they  
should be. This is really the primary job of a GC, the secondary job,  
which most people think of what a GC does, is to allow the resources  
used by objects which be provedn to be no longer be reachable from  
that root set to be reused.

The root set comprised references such as:

Any constants in the outermost name space, (e.g. the object which is  
referenced by say Array)  
Any references currently on the activation stack of running threads.  
These references will be things like method invocation parameter  
values, local temporary variable values, and block argument values.

The reachable objects are those referenced by any reference in the  
root set, any object referenced by any of the variables within those  
objects etc. etc.

The effect of a variable going out of scope (e.g. a temporary on the  
invocation frame of a method which has returned), is that that  
reference is no longer part of the root set. but if there is at least  
one other reference to the object in question reachable from somewhere  
else in the root set then that object WILL NOT be reclaimed by a  
bug-free garbage collector.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
Twitter: @RickDeNatale  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 14, 2010, 12:11am UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/17 "2010-07-14T00:11:03Z")

</div>

Abder-Rahman A. wrote:

> In the “Why’s poignant guide to Ruby” book, it states the following:
> 
> “If you can’t get to an object through a variable, then Ruby will figure  
> you are done with it and will get rid of it. Periodically, Ruby sends  
> out its garbage collector to set these objects free.”
> 
> The point I’m not getting here is: “If you can’t get to an object  
> through a variable…”
> 
> Can you provide an examples that illustrates this?

Here’s an example to play with:

class C; end

def make\_one  
$c = C.new  
nil # Can you guess why this is here?  
end

def clear!  
$c = nil  
end

# How many reachable C instances are there?

# (Note: works in MRI, but maybe not others, such as jruby)

def how\_many?  
p ObjectSpace.each\_object© {}  
end

GC.start  
how\_many? # =\> 0  
make\_one  
how\_many? # =\> 1  
make\_one  
how\_many? # =\> 2  
clear!  
how\_many? # =\> 2  
GC.start  
how\_many? # =\> 0

* * *

As Rick pointed out (“variables don’t get collected, objects do”), the  
question of variable scope is not really the important one. In the above  
example, $c is always in scope, because it is a global. What’s important  
is whether an object can be reached from the value assigned to $c.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 13, 2010, 9:12pm UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/18 "2010-07-13T21:12:48Z")

</div>

Thanks everyone for your valuable information.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 14, 2010, 12:13am UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/19 "2010-07-14T00:13:18Z")

</div>

Thanks a lot all.

---

<div class="post-metadata">

**Author:** ![swengineer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@swengineer](https://www.ruby-forum.com/u/swengineer)\
**Post date:** [July 14, 2010, 4:08am UTC](https://www.ruby-forum.com/t/ruby-garabage-collector/191508/20 "2010-07-14T04:08:43Z")

</div>

On Wed, 14 Jul 2010 00:40:05 +0900, Bruno A wrote:

> > Can you provide an examples that illustrates this?
> > 
> > Thanks.
> 
> a = [1,2,3].find {|x| x \> 3}
> 
> puts a
> 
> In this (maybe too simple) example, x is garbage-collected once flow  
> leaves the block.

Nothing gets garbage collected here becuase 1,2, and 3 are value objects  
(they’re special in that they’re not stored on the heap, but stored in  
the memory that would be the pointer to most other objects), and because  
they’re still accessible through the array (a points to an array, which  
points to each of the array’s 3 elements) even after the loop ends.

A better example is:

irb(main):001:0\> a=Object.new  
=\> #Object:0x7f361c5dbe58  
irb(main):002:0\> a=Object.new  
=\> #Object:0x7f361c5d1c50

at the end of this program, there is no longer a variable that points  
(either directly or indirectly) to #Object:0x7f361c5dbe58, so it can  
be  
garbage collected.

irb(main):003:0\> a=[]  
=\> []  
irb(main):004:0\> b=Object.new  
=\> #Object:0x7f361c5c33d0  
irb(main):005:0\> a \<\< b  
=\> [#Object:0x7f361c5c33d0]  
irb(main):006:0\> b=Object.new  
=\> #Object:0x7f361c5a9890  
irb(main):007:0\> a \<\< b  
=\> [#Object:0x7f361c5c33d0, #Object:0x7f361c5a9890]  
irb(main):008:0\> b=Object.new  
=\> #Object:0x7f361c5941c0

In this example, nothing gets garbage collected. I allocated three  
Objects, and one Array. At the end of execution, the Array is pointed to  
by a, and two of the Objects are pointed to by the Array. The third  
Object is pointed to by b.

[Next page](https://www.ruby-forum.com/t/ruby-garabage-collector/191508.md?page=2)
