オブジェクトの配列を表す配列を含む行列型がありvoid*
ます(たとえば、すべてのC整数、すべてのfloat、double、さまざまな構造体、場合によってはすべてのRubyなど、特定の行列の1つの型すべてですVALUE
) 。
sの行列を作成しようとするまで、メモリ割り当てとガベージコレクションは正しく機能しているようVALUE
です。
次のマーク関数を定義しています。
void mark_dense_storage(void* s) {
size_t i;
DENSE_STORAGE* storage = (DENSE_STORAGE*)s;
if (storage && storage->dtype == RUBY_OBJECT)
for (i = 0; i < count_dense_storage_elements(s); ++i)
rb_gc_mark(*((VALUE*)(storage->elements + i*sizeof(VALUE)));
}
したがって、実際にVALUE
行列である場合にのみマーキングを行います。それ以外の場合は、マーク関数NULL
に渡されます。Data_Wrap_Struct
VALUE
しかし、いくつかの行列関数をテストすると、セグメンテーション違反が発生します(要点を参照)。
VALUE*
具体的には、配列の最初のオブジェクトでRubyメソッドを初めて呼び出そうとすると、セグメンテーション違反が発生するようです。
C[i+j*ldc] = rb_funcall(C[i+j*ldc], nm_id_mult, 1, beta); // C[i+j*ldc] = C[i+j*ldc]*beta
nm_id_mult
Init
私の関数でとして定義されたグローバルrb_intern("*")
です。
これはガベージコレクションの問題ではない可能性がありますが、GCは私が最も理解していないRubyの一部です。また、私のセグメンテーション違反も、投稿者がGCに起因するこのトレースとほぼ同じです。
だから、私の質問:
VALUE
GCの場合、 sの配列をマークする適切な方法は何ですか?GCでない場合、このタイプのエラーを診断するにはどうすればよいですか?私はそのようなものを見たことがありません。
編集:
VALUE
これは、 Cで作成されたsの初期化に失敗した例であることがわかりました。
つまり、*(VALUE*)a = INT2FIX(0)
にアクセスする前に必ず実行してくださいa
。
私はまだその質問が適切だと思います。StackOverflowやその他の場所で、クリーンアンドスイープガベージコレクションのマーキングの本当に良い例を見つけることができませんでした。そのような例や説明を提供していただければ、それをこの質問に対する正解としてマークします。