我遇到这种情况,我必须在ruby线程内部而不是ruby线程中用C ++代码构造一些更大的ruby数据结构。
在堆栈上创建的ruby对象是否必须经过特殊处理才能被ruby GC收集?如果对象是在红宝石或非红宝石线上创建的,它会有什么不同吗?
示例:
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 托
答案 0 :(得分:1)
根据我的理解,GC扫描所有堆栈中的任何看起来像是指向ruby对象的指针,并以这种方式将其发现的任何内容视为正在使用的对象。
据我所知,在非ruby线程上创建ruby对象并不支持