# Method returning a hash, is the hash in the heap?

**URL:** <https://www.ruby-forum.com/t/method-returning-a-hash-is-the-hash-in-the-heap/188894>\
**Category:** Ruby\
**Created:** [May 20, 2010, 4:24am UTC](https://www.ruby-forum.com/t/method-returning-a-hash-is-the-hash-in-the-heap/188894 "2010-05-20T04:24:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![winterheat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7993a0/32.png) [@winterheat](https://www.ruby-forum.com/u/winterheat)\
**Post date:** [May 20, 2010, 4:24am UTC](https://www.ruby-forum.com/t/method-returning-a-hash-is-the-hash-in-the-heap/188894/1 "2010-05-20T04:24:05Z")

</div>

For this program:

class Point  
def initialize(x,y)  
@x,@y = x,y  
@something = 123.456  
end

def instance\_variables\_and\_values  
hash = {}  
instance\_variables.each {|n| hash[n] = instance\_variable\_get(n)}  
return hash  
end

end

p1 = Point.new(1,2)  
p p1.instance\_variables\_and\_values

p2 = Point.new(3,4)  
p p1.instance\_variables\_and\_values  
p p2.instance\_variables\_and\_values

so the hash is actually allocated in the Heap, and the local variable in  
the Stack is just the “hash” reference?

So when the method returns, the “hash” variable, which is just a  
reference to the hash object, is destroyed. But the hash object that is  
in the Heap will stay as long as there is a reference to it (a reference  
from outside)?

---

<div class="post-metadata">

**Author:** ![winterheat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7993a0/32.png) [@winterheat](https://www.ruby-forum.com/u/winterheat)\
**Post date:** [May 20, 2010, 9:58am UTC](https://www.ruby-forum.com/t/method-returning-a-hash-is-the-hash-in-the-heap/188894/2 "2010-05-20T09:58:58Z")

</div>

2010/5/20 Jian L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> instance\_variables.each {|n| hash[n] = instance\_variable\_get(n)}  
> p p2.instance\_variables\_and\_values
> 
> so the hash is actually allocated in the Heap, and the local variable in  
> the Stack is just the “hash” reference?

It is just _a_ reference - there can be multiple references to an  
instance and none of them is special.

> So when the method returns, the “hash” variable, which is just a  
> reference to the hash object, is destroyed. But the hash object that is  
> in the Heap will stay as long as there is a reference to it (a reference  
> from outside)?

Yep, basically that’s it. I would pick a tad different wording but  
you have grokked the essence of it.

With references we usually do not speak of “destruction” because that  
is something typically done to objects. References are simply  
forgotten or lost, I would say.

The lifetime of an instance is more accurately described as “from its  
creation until GC decides to remove it”. Of course, the earliest  
point in time when GC can decide to remove it is after the last  
reference to the instance has gone. (Note there is a special case  
with WeakReference but I don’t want to complicate things too much  
initially. There are also ways to access an instance during the period  
between “last ref gone” and “GC removed it” via ObjectSpace but this  
is not something you should rely on.)

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![winterheat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7993a0/32.png) [@winterheat](https://www.ruby-forum.com/u/winterheat)\
**Post date:** [May 20, 2010, 12:17pm UTC](https://www.ruby-forum.com/t/method-returning-a-hash-is-the-hash-in-the-heap/188894/3 "2010-05-20T12:17:29Z")

</div>

Robert K. wrote:

> The lifetime of an instance is more accurately described as “from its  
> creation until GC decides to remove it”. Of course, the earliest  
> point in time when GC can decide to remove it is after the last  
> reference to the instance has gone. (Note there is a special case  
> with WeakReference but I don’t want to complicate things too much  
> initially. There are also ways to access an instance during the period  
> between “last ref gone” and “GC removed it” via ObjectSpace but this  
> is not something you should rely on.)

yes, because previous, I was thinking that any local variables will get  
erased and the stack will shrink, so in this case, the hash seems valid  
and it is actually a new object creation, something that is like a  
malloc()… and it resides in the heap.

for the WeakReference… the wiki explanation is “weakly reachable”… I  
thought it can be garbage collected when there is not usable reference  
that can reach that object… but what if it is still “reachable, but  
weakly”, then it can still be garbage collected? Then won’t the  
reference to it and its usage cause a segmentation fault or similar  
error?

---

<div class="post-metadata">

**Author:** ![winterheat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7993a0/32.png) [@winterheat](https://www.ruby-forum.com/u/winterheat)\
**Post date:** [May 20, 2010, 1:16pm UTC](https://www.ruby-forum.com/t/method-returning-a-hash-is-the-hash-in-the-heap/188894/4 "2010-05-20T13:16:49Z")

</div>

2010/5/20 Jian L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> yes, because previous, I was thinking that any local variables will get  
> erased and the stack will shrink, so in this case, the hash seems valid  
> and it is actually a new object creation, something that is like a  
> malloc()… and it resides in the heap.

Exactly.

> for the WeakReference… the wiki explanation is “weakly reachable”… I  
> thought it can be garbage collected when there is not usable reference  
> that can reach that object… but what if it is still “reachable, but  
> weakly”, then it can still be garbage collected?

Yes.

> Then won’t the  
> reference to it and its usage cause a segmentation fault or similar  
> error?

No, you WeakRef#weakref\_alive? will simply return false and  
WeakRef# **getobj** will just throw WeakRef::RefError which you will  
also see for any other method.

irb(main):018:0\> r.weakref\_alive?  
=\> false  
irb(main):019:0\> r.to\_s  
WeakRef::RefError: Invalid Reference - probably recycled  
from (irb):18  
from /opt/bin/irb19:12:in `’  
irb(main):020:0\>

The Ruby heap is not exactly the same as a heap in languages like C:  
in C you directly dereference memory pointers and if there is an error  
you’ll get a segfault. In Ruby (as in Java as well) the runtime  
system manages memory accesses and you will never see a segfault  
(unless there is a bug in the runtime or in a C extension).

Kind regards

robert
