Tobi
2/13/2009 10:24:00 AM
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