1

我的情况是,我必须在 C++ 代码中从 ruby​​ 线程而不是 ruby​​ 线程中构建一些更大的 ruby​​ 数据结构。

在堆栈上创建的 ruby​​ 对象是否必须经过特殊处理才能不被 ruby​​ GC 收集?如果对象是在 ruby​​ 或非 ruby​​ 线程上创建的,有什么区别吗?

例子:

VALUE h = rb_hash_new(); 
VALUE k = rb_str_new2( "foo" );
VALUE v = rb_str_new2( "foo" );
rb_hash_aset( h, k, v );

我希望每个函数调用都可以分配内存,从而调用垃圾收集器。我是否必须特别注意保护 h、k 和 v 不被收集,直到它们可以通过任何全局变量访问?也许是这样的:

VALUE h = Qnil;
VALUE k = Qnil;
VALUE v = Qnil;
rb_gc_register_address( &h ); 
rb_gc_register_address( &k ); 
rb_gc_register_address( &v ); 

VALUE k = rb_str_new2( "foo" );
VALUE v = rb_str_new2( "foo" );

rb_hash_aset( h, k, v );

rb_gc_unregister_address( &k ); 
rb_gc_unregister_address( &v ); 

第二个版本要复杂得多,所以我想避免它,如果有任何保证 GC 扫描所有线程以查找可能的引用。

编辑:我刚刚意识到,我可能不应该使用 rb_gc 之类的函数...来自不包含 gvl 的非 ruby​​ 线程。因此,保证 GC 将标记来自 ruby​​ 堆栈的引用就足够了。

TIA 托尔斯滕

4

1 回答 1

1

据我了解,GC 会扫描您的所有堆栈以查找任何看起来像指向 ruby​​ 对象的指针的内容,并将以这种方式找到的任何内容视为正在使用的对象。

据我所知,不支持在非 ruby​​ 线程上创建 ruby​​ 对象

于 2012-07-17T08:45:51.323 回答