나는 모든 객체의 배열을 나타내는 void*
배열을 포함하는 행렬 유형을 가지고 있습니다 (예 : 모든 C 정수, 모든 float, double, 다양한 구조체 또는 가능한 모든 배열). 루비 VALUE
s).Ruby 확장의 VALUE * 배열에서 마킹을 수행하는 방법은 무엇입니까?
VALUE
의 행렬을 만들려고 시도하기 전에는 메모리 할당 및 가비지 수집이 올바르게 작동하는 것 같습니다. - 그렇지 않으면 NULL
이 마크 기능을 위해 Data_Wrap_Struct
에 전달되는이 실제로 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
행렬 함수 (see gist)을 테스트 할 때 segfault가 발생합니다.
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
는 rb_intern("*")
로 내 Init
기능에 정의 된 전역 :
특히, 내가 VALUE*
배열의 첫 번째 객체에 루비 메서드를 호출하려고 처음 세그 폴트 것으로 보인다.
가비지 수집 문제는 아니지만 GC는 Ruby에서 가장 이해할만한 부분입니다. 또한 segfault는 포스터가 GC에 부여하는 this trace과 거의 동일합니다.
그래서, 내 질문 : 그것은 GC의 경우
,
VALUE
의 배열을 표시하는 적절한 방법은 무엇입니까?GC가 아닌 경우 어떻게 이런 유형의 오류를 진단해야합니까? 나는 그런 것을 본 적이 없다.
편집 :
이 당신이 액세스를 시도하기 전에 *(VALUE*)a = INT2FIX(0)
을 할 수 있는지 확인하십시오, C.
을 만들어 VALUE
의 초기화 실패의 예임을 밝혀 a
.
나는 여전히 질문이 적절하다고 생각합니다. StackOverflow 나 그 밖의 곳에서 클린 - 스윕 쓰레기 수거를위한 마킹에 대한 좋은 예를 찾을 수 없었습니다. 그러한 예제 나 설명을 제공 할 수 있다면이 질문에 대한 정답으로 표시 할 것입니다.
어떤 Ruby 버전입니까? –
루비 1.9.3p0 (2011-10-30 수정 33570)입니다. –
먼저 Ruby 1.9.3-p125로 업그레이드하고 문제가 아직 있는지 확인하십시오. p0에 GC와 관련된 몇 가지 문제가있었습니다. –