[#31647] [Backport #3666] Backport of r26311 (Bug #2587) — Luis Lavena <redmine@...>

Backport #3666: Backport of r26311 (Bug #2587)

13 messages 2010/08/07

[#31666] [Bug #3677] unable to run certain gem binaries' in windows 7 — Roger Pack <redmine@...>

Bug #3677: unable to run certain gem binaries' in windows 7

10 messages 2010/08/10

[#31676] [Backport #3680] Splatting calls to_ary instead of to_a in some cases — Tomas Matousek <redmine@...>

Backport #3680: Splatting calls to_ary instead of to_a in some cases

10 messages 2010/08/11

[#31681] [Bug #3683] getgrnam on computer with NIS group (+)? — Rocky Bernstein <redmine@...>

Bug #3683: getgrnam on computer with NIS group (+)?

13 messages 2010/08/11

[#31843] Garbage Collection Question — Asher <asher@...>

This question is no doubt a function of my own lack of understanding, =

17 messages 2010/08/25
[#31861] Re: Garbage Collection Question — Roger Pack <rogerdpack2@...> 2010/08/26

> The question in short: when an object goes out of scope and has no

[#31862] Re: Garbage Collection Question — Asher <asher@...> 2010/08/26

Right - so how does a pointer ever get off the stack?

[#31873] Re: Garbage Collection Question — Kurt Stephens <ks@...> 2010/08/27

On 8/26/10 11:51 AM, Asher wrote:

[#31894] Re: Garbage Collection Question — Asher <asher@...> 2010/08/27

I very much appreciate the response, and this is helpful in describing =

[#31885] Avoiding $LOAD_PATH pollution — Eric Hodel <[email protected]>

Last year Nobu asked me to propose an API for adding an object to

21 messages 2010/08/27

[#31947] not use system for default encoding — Roger Pack <rogerdpack2@...>

It strikes me as a bit "scary" to use system locale settings to

19 messages 2010/08/30

[#31971] Change Ruby's License to BSDL + Ruby's dual license — "NARUSE, Yui" <naruse@...>

Ruby's License will change to BSDL + Ruby's dual license

16 messages 2010/08/31

[ruby-core:31861] Re: Garbage Collection Question

From: Roger Pack <rogerdpack2@...>
Date: 2010-08-26 16:32:17 UTC
List: ruby-core #31861
> The question in short: when an object goes out of scope and has no
> references that were left to it, how does it get collected? Conceptually
> this seems easy - the GC walks the heap to see if the contents are still
> valid pointers to the heap. Once the pointer is invalid, it makes total
> sense to me how the rest proceeds. But how does the pointer to the heap e=
ver
> become invalid?


It walks the stack, and (for sake of ease of understanding) marks all
pointers still on the stack as "live"
then it marks all of their children as "live"
then all of their grandchildren, etc.

Then it traverses the entire heap, looking for objects that haven't
been marked as live, and "frees" them.

NB that these two stages are separate, so they don't conflict.
HTH.
-r



> Hopefully my example and summary will clarify:
>
> require 'pp'
> class Hash::Weak < Hash
>
> =A0=A0def []( key )
> =A0=A0 =A0# get the stored ID - a FixNum, not an object reference to our
> weak-referenced object
> =A0=A0 =A0obj_id =3D super( key.to_sym )
> =A0=A0 =A0# theoretically this should cause non-referenced objects to get=
 cleaned
> up
> =A0=A0 =A0# so long as nothing looks like a pointer or reference to it
> =A0=A0 =A0ObjectSpace.garbage_collect
> =A0=A0 =A0# now get our object from ID
> =A0=A0 =A0# if it had no references it should have been GC'd and we shoul=
d get an
> =A0=A0 =A0# rb_eRangeError "is not id value" (expected) or "is recycled o=
bject"
> (possible)
> =A0=A0 =A0obj =3D ObjectSpace._id2ref( obj_id )
> =A0=A0 =A0return obj
> =A0=A0end
>
> =A0=A0def []=3D( key, object )
> =A0=A0 =A0# FixNum have a constant ID for value, so can't be copied and c=
an't be
> garbage collected
> =A0=A0 =A0# so object.__id__ cannot be a reference to a child of object a=
nd
> therefore cannot prevent
> =A0=A0 =A0# garbage collection on the object
> =A0=A0 =A0super( key.to_sym, object.__id__ )
> =A0=A0end
>
> end
> ##################################################
> weak_hash =3D Hash::Weak.new
> class TestClass
> end
> test_object =3D TestClass.new
> puts 'storing test object'
> weak_hash[ :key ] =3D test_object
> puts 'hash now contains object id: ' + weak_hash.pretty_inspect
> print 'retrieving stored test object from hash (should work/be non-nil): =
'
> valid_key =3D weak_hash[ :key ]
> pp valid_key
> class AnotherClass
> end
> puts 'setting variable referring to test object (ID: ' +
> test_object.__id__.to_s + ') to nil'
> test_object =3D nil
> puts 'ID for variable referring to test object is now: ' +
> test_object.__id__.to_s
> print 'getting test object (should fail with rb_eRangeError): '
> invalid_key =3D weak_hash[ :key ]
> pp invalid_key
> # error - returns valid key
> ##################################################
> # object is created, given an id
> # variable is assigned to id
> # variable is changed to new object (including nil)
> # variable gets the id of new object
> # previous reference made by variable remains in object space (no valid
> references)
> # gc starts
> # rb_gc_mark calls gc_mark, marks VM instance (#<RubyVM:0x000001008700b8>=
)
> # gc_mark calls gc_mark_children, marks all children of VM
> # first, the VM class (RubyVM), and then its children
> # =A0 then its class instance (#<Class:RubyVM>), and then its children
> # =A0 =A0 then its class instance (#<Class:#<Class:RubyVM>>) and its chil=
dren
> # =A0 =A0 =A0 then its class instance (#<Class:#<Class:Class>>) and its c=
hildren
> # =A0 =A0 =A0 =A0 then gc_mark_children calls mark_tbl to mark its table =
(the class
> table)
> # =A0 =A0 =A0 =A0 =A0 mark_tbl marks all children of the class table, sta=
rting with
> Class
> # =A0 =A0 =A0 =A0 =A0 =A0 Class marks its children, first of all #<Class:=
Module>
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 #<Class:Module> marks its children, first o=
f all
> #<Class:#<Class:Module>>
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #<Class:#<Class:Module>> marks its chil=
dren, which
> includes a table of classes
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mark_tbl marks each of classes, whi=
ch first includes
> #<Class:Object>
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #<Class:Object> has a table of =
entries that it marks,
> first of all Object
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Object has a table that it =
marks, first of all its
> binding context (presumably main first?) #<Binding:0x00000100870068>
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #<Binding:0x00000100870=
068> marks its children,
> which calls binding_mark, which calls rb_gc_mark, which calls gc_mark on =
the
> Ruby environment: #<RubyVM::Env:0x00000100854bd8>
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 #<RubyVM::Env:0x000=
00100854bd8> marks its
> children which calls env_mark
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 env_mark calls =
rb_gc_mark_locations on the
> range covered by the environment's declared memory space, which calls
> gc_mark_locations
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gc_mark_loc=
ations calls mark_locations_array
> on the space marked by the start and length of environment
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mark_lo=
cations_array looks at the
> environment as an array of long, and calls is_pointer_to_heap on each one
> # =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if =
(long)slice is the address of a valid
> pointer on the heap, returns TRUE, which causes gc_mark to be called on t=
he
> object
> #***** =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0obj=
ect, defined by ID, matches with
> (long)slice because it has not yet been collected; it is therefore marked=
 as
> still existing because it has a valid pointer
> # =3D> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0if this were true, no object would
> ever be garbage collected; so how is any object ever garbage collected?
>
> Any help understanding what's going on is much appreciated.
> Thanks,
> Asher

In This Thread