Holding a reference to a ruby object outside the interpreter

Ask a Question related to Ruby, Design and Development.

  1. #1

    Default Holding a reference to a ruby object outside the interpreter

    How can I hold a reference to a ruby object outside the interpreter?
    Ie, how can I prevent it from being garbage collected if my (external)
    reference is the only one.

    In .net I can use a System.Runtime.InteropServices.GCHandle if I want
    to hold a reference to a managed object in unmanaged code. Calling
    GCHandle.Alloc(object anObject) pins the objects address so the GC
    will never move it and prevents the object from being gc'ed before the
    handle is release by calling its Free() method.

    What is the equivalent technique in ruby?

    /Thomas
    Thomas Guest

  2. Similar Questions and Discussions

    1. Unable to resize object in proportion by holding shift key
      When selecting an object (text or otherwise) I have been able to constrain proportion by holding down shift while draging the object larger/smaller....
    2. holding a connection object across several ASP pages
      Hi. I am new to ASP. I need to create a "wizard" using a SQL 7 database that will display a few forms and collect data from the user. My initial...
    3. Thread safety: Serializing access to ruby interpreter- again
      I recently asked about this and got answers, but here I go again: How can I efficiently serialize access to the ruby interpreter. I have to make...
    4. Ruby interpreter thread safety
      I have a scenario where a ruby extension module starts real/os/heavy-weight threads that may call back to ruby. As far as I understand the ruby...
    5. Ruby tcltklib includes a Tcl interpreter
      I just discovered something I didn't know that I think others might be interested in. Ruby tcltklib includes a tcl/tk interpreter. The interpreter...
  3. #2

    Default Re: Holding a reference to a ruby object outside the interpreter

    Thomas wrote:
    > How can I hold a reference to a ruby object outside the interpreter?
    > Ie, how can I prevent it from being garbage collected if my (external)
    > reference is the only one.
    >
    > In .net I can use a System.Runtime.InteropServices.GCHandle if I want
    > to hold a reference to a managed object in unmanaged code. Calling
    > GCHandle.Alloc(object anObject) pins the objects address so the GC
    > will never move it and prevents the object from being gc'ed before the
    > handle is release by calling its Free() method.
    >
    > What is the equivalent technique in ruby?
    There are several ways you can do this:

    If the VALUE (which is the C data type that points to a Ruby object) is
    on the stack, so long as it doesn't go out of scope, Ruby will not
    collect the object. This means that, for objects you create for use
    during a function call, you don't need to do ANYTHING; Ruby protects it
    until your function returns.

    Another way to do it is to create a C VALUE variable globally or as part
    of a class. You can call rb_gc_register_address to register the memory
    space holding the VALUE. So long as your variable exists, Ruby protects
    the object it points to. When you are done with the object, call
    rb_gc_unregister_address.

    If you don't have a fixed memory location holding a VALUE, you can just
    called rb_global_variable to register the object as an unnamed global,
    and it will NEVER get collected. This is sort of brutal and can lead to
    memory leaks because the object never goes away.

    The last way I know of is if you use Data_Make_Struct or
    Data_Wrap_Struct to wrap your own C data type (a struct or whatever) as
    a Ruby object, and your data type has VALUEs pointing to objects and you
    want them to be treated as "children" to your object. You must provide
    a "mark" function which marks those VALUEs when your object gets marked
    (making them ineligible for collection).

    Sean O'Dell

    Sean O'Dell Guest

  4. #3

    Default Re: Holding a reference to a ruby object outside the interpreter

    > If the VALUE (which is the C data type that points to a Ruby object) is
    > on the stack, so long as it doesn't go out of scope, Ruby will not
    > collect the object. This means that, for objects you create for use
    > during a function call, you don't need to do ANYTHING; Ruby protects it
    > until your function returns.
    My reference will be stored on the managed heap in .net and will not
    be on the stack.
    > Another way to do it is to create a C VALUE variable globally or as part
    > of a class. You can call rb_gc_register_address to register the memory
    > space holding the VALUE. So long as your variable exists, Ruby protects
    > the object it points to. When you are done with the object, call
    > rb_gc_unregister_address.
    Well this interests me. You say I need to allocate it globally? Can I
    store it on the (unmanaged) heap?

    I dug out the source for rb_register_address

    void
    rb_gc_register_address(addr)
    VALUE *addr;
    {
    struct gc_list *tmp;

    tmp = ALLOC(struct gc_list);
    tmp->next = global_List;
    tmp->varptr = addr;
    global_List = tmp;
    }

    And it seems it adds the VALUE *addr to a linked list, which I guess
    will then be protected from gc'ing. It seems allocating the VALUE on
    the heap should be perfectly safe. Is it?

    This would work for me, as I can keep a reference to the unmanaged
    heap object from managed space. and clean it up when the managed
    reference goes away.

    Cheers,

    Thomas
    Thomas Guest

  5. #4

    Default Re: Holding a reference to a ruby object outside the interpreter

    Thomas wrote:
    >>If the VALUE (which is the C data type that points to a Ruby object) is
    >>on the stack, so long as it doesn't go out of scope, Ruby will not
    >>collect the object. This means that, for objects you create for use
    >>during a function call, you don't need to do ANYTHING; Ruby protects it
    >>until your function returns.
    >
    >
    > My reference will be stored on the managed heap in .net and will not
    > be on the stack.
    >
    >
    >>Another way to do it is to create a C VALUE variable globally or as part
    >>of a class. You can call rb_gc_register_address to register the memory
    >>space holding the VALUE. So long as your variable exists, Ruby protects
    >>the object it points to. When you are done with the object, call
    >>rb_gc_unregister_address.
    >
    >
    > Well this interests me. You say I need to allocate it globally? Can I
    > store it on the (unmanaged) heap?
    >
    > I dug out the source for rb_register_address
    >
    > void
    > rb_gc_register_address(addr)
    > VALUE *addr;
    > {
    > struct gc_list *tmp;
    >
    > tmp = ALLOC(struct gc_list);
    > tmp->next = global_List;
    > tmp->varptr = addr;
    > global_List = tmp;
    > }
    >
    > And it seems it adds the VALUE *addr to a linked list, which I guess
    > will then be protected from gc'ing. It seems allocating the VALUE on
    > the heap should be perfectly safe. Is it?
    >
    > This would work for me, as I can keep a reference to the unmanaged
    > heap object from managed space. and clean it up when the managed
    > reference goes away.
    That should work just fine; with register_address, it's only important
    that the memory space for the VALUE doesn't go away, so any memory heap
    should do (assuming .net doesn't do some sort of weird virtual memory
    thing where the memory space you allocate can move around).

    Sean O'Dell

    Sean O'Dell Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139