method returning a hash, is the hash in the heap?

J

Jian Lin

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)?
 
R

Robert Klemme

2010/5/20 Jian Lin said:
For this program:

class Point
=A0def initialize(x,y)
=A0 =A0@x,@y =3D x,y
=A0 =A0@something =3D 123.456
=A0end

=A0def instance_variables_and_values
=A0 =A0hash =3D {}
=A0 =A0instance_variables.each {|n| hash[n] =3D instance_variable_get(n)}
=A0 =A0return hash
=A0end

end

p1 =3D Point.new(1,2)
p p1.instance_variables_and_values

p2 =3D 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?

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. =A0But the hash object that i= s
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


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
J

Jian Lin

Robert said:
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?
 
R

Robert Klemme

2010/5/20 Jian Lin said:
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.

=A0Then 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?
=3D> false
irb(main):019:0> r.to_s
WeakRef::RefError: Invalid Reference - probably recycled
from (irb):18
from /opt/bin/irb19:12:in `<main>'
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

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,979
Messages
2,570,185
Members
46,728
Latest member
FernMcmull

Latest Threads

Top