rb_protect / rb_eval_string and the GC in Ruby 1.8.7

T

Tobi

Hi!

At the moment I'm trying to extend an application with embedded Ruby and
therefore try to understand the garbage collection mechanisms.

For a simple class that just prints when it's ctor and dtor are called,
I've created the Ruby wrapping code with Swig. Now I do this:

in Ruby:

def get_new_bar
puts "DEBUG: get_new_bar"
return Swig::Bar.new
end

In C++:

...
rb_eval_string("get_new_bar");
rb_eval_string("puts 'DEBUG: <GC>'; GC.start; puts 'DEBUG: </GC>'");
...
ruby_finalize();


What happens is exactly, what one would expect:

DEBUG: Bar::Bar()
DEBUG: get_new_bar
DEBUG: <GC>
DEBUG: Bar::~Bar();
DEBUG: </GC>

Now I change this to:

...
rb_protect(get_new_bar_eval_wrapper, 0, &error);
rb_eval_string("puts 'DEBUG: <GC>'; GC.start; puts 'DEBUG: </GC>'");
...
ruby_finalize();

But what happens now is:

DEBUG: Bar::Bar()
DEBUG: get_new_bar
DEBUG: <GC>
DEBUG: </GC>
DEBUG: Bar::~Bar();


As soon as I call rb_protect() a second time with completely different
code, the object allocated in the previous rb_protect call will be deleted
in the next GC run.

The question is: Why doesn't the GC delete the Bar instance when I create
it within rb_protect()? Is the Bar instance referenced by a global
variable somewhere? Are there any threading issues I should be aware of
with rb_protect()?

This only happens in Ruby 1.8.7. In 1.9.0 there is no difference between
the direct call and the rb_protect wrapped call.

Thx,

Tobias
 

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,769
Messages
2,569,582
Members
45,060
Latest member
BuyKetozenseACV

Latest Threads

Top