1

私は、Ruby スレッドではなく、Ruby スレッド内から C++ コードでいくつかのより大きな 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 ); 

2 番目のバージョンははるかに複雑なので、GC がすべてのスレッドをスキャンして参照の可能性を探すという保証がある場合は、これを避けたいと思います。

編集:おそらくrb_gcのような関数を使用すべきではないことに気づきました... gvlを保持しない非ルビースレッドから。したがって、GC が Ruby スタックからの参照をマークするという保証があれば十分です。

TIAトルステン

4

1 に答える 1

1

私が理解しているように、GCはすべてのスタックをスキャンして、rubyオブジェクトへのポインターのように見えるものを探し、この方法で見つけたものを使用中のオブジェクトと見なします。

私の知る限り、非ルビースレッドでルビーオブジェクトを作成することはサポートされているものではありません

于 2012-07-17T08:45:51.323 に答える