IRB + C Extension = Memory Loss

R

Ryan Bates

I'm having difficult making a simple C extension. The struct's memory
seems to go missing after a while when using IRB. I'm no C expert, so
I'm probably doing something wrong as far as memory allocation is
concerned. Here's the problem and the code:

http://gist.github.com/11611

Notice the greeting goes away after calling "h.greet" a number of
times? This only seems to happen in IRB and not through a ruby script.
Any idea why? I'm assuming it has something to do with Ruby's garbage
collection, but I don't know how to solve it.

Thanks,

Ryan
 
T

Tim Hunter

Ryan said:
I'm having difficult making a simple C extension. The struct's memory
seems to go missing after a while when using IRB. I'm no C expert, so
I'm probably doing something wrong as far as memory allocation is
concerned. Here's the problem and the code:

http://gist.github.com/11611

Notice the greeting goes away after calling "h.greet" a number of
times? This only seems to happen in IRB and not through a ruby script.
Any idea why? I'm assuming it has something to do with Ruby's garbage
collection, but I don't know how to solve it.

Thanks,

Ryan

GC is collecting the greeting string because it thinks there are no
references to it. Your hello_mark function needs to identify the
greeting string object as "in use". From the Pickaxe:

"The mark routine will be called by the garbage collector during its
``mark'' phase. If your structure references other Ruby objects, then
your mark function needs to identify these objects using
rb_gc_mark(value)."
 
R

Ryan Bates

Thanks! That makes sense. Calling rb_gc_mark(*hello->greeting) in the
hello_mark method works.

On a related note. What if I need to re-assign greeting to a new
string at some point in the future after hello_mark has been called.
Should I call rb_gc_mark upon assignment (outside of hello_mark)?

Regards,

Ryan
 
T

Tim Hunter

Ryan said:
Thanks! That makes sense. Calling rb_gc_mark(*hello->greeting) in the
hello_mark method works.

On a related note. What if I need to re-assign greeting to a new
string at some point in the future after hello_mark has been called.
Should I call rb_gc_mark upon assignment (outside of hello_mark)?

Regards,

Ryan

Let's back up a bit. I assume you're storing the VALUE passed into
hello_init in hello->greeting:

static VALUE hello_init(VALUE obj, VALUE greeting)
{
HELLO(obj)->greeting = greeting;
return Qnil;
}

The VALUE represents the String object, which is what Ruby is interested
in. In that case, you should call rb_gc_mark(hello->greeting) so Ruby
can mark the String object, not the C string embedded in the object.

Regarding your new question, when you want to assign a new greeting
String object, just store the new VALUE in hello->greeting. The old
greeting String won't get marked during the next GC sweep, so GC will
know that it's available for collection.

(I hope this makes sense. It's so hard to make sense on Friday afternoon
:)
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top