문제

나는 void* 배열, 객체의 배열을 나타냅니다(주어진 행렬에서 모두 동일한 유형입니다(예: 모든 C 정수, 모든 부동 소수점, 복식, 다양한 구조체 또는 모든 Ruby). VALUE에스).

메모리 할당 및 가비지 수집이 다음과 같은 행렬을 생성하려고 시도하기 전까지는 올바르게 작동하는 것 같습니다. 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 행렬 함수 (요지 참조).

특히, 처음으로 Ruby 메서드를 호출할 때 세그폴트가 발생하는 것 같습니다. VALUE* 정렬:

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의 일부입니다. 그리고 내 segfault도 거의 동일합니다. 이 흔적, 포스터는 GC에 귀속됩니다.

그래서 내 질문은 다음과 같습니다.

  1. GC인 경우 배열을 표시하는 적절한 방법은 무엇입니까? VALUE에스?

  2. GC가 아닌 경우 이러한 유형의 오류를 진단하려면 어떻게 해야 합니까?나는 그런 것을 본 적이 없습니다.

편집하다:

초기화 실패의 예인 것으로 밝혀졌습니다. VALUEC로 작성되었습니다.

다시 말해, 반드시 하세요. *(VALUE*)a = INT2FIX(0) 접근을 시도하기 전에 a.

나는 여전히 그 질문이 관련성이 있다고 생각합니다.StackOverflow나 다른 곳에서 정리 및 청소 가비지 수집 표시에 대한 정말 좋은 예를 찾지 못했습니다.그러한 예 및/또는 설명을 제공할 수 있다면 이를 이 질문에 대한 정답으로 표시하겠습니다.

도움이 되었습니까?

해결책

Ruby의 마크 앤 스윕 GC는 두 단계로 작동합니다.

첫 번째 단계에서는 실시간 개체를 표시합니다.알려진 각 "라이브 객체"의 표시 기능을 호출하여 재귀적으로 작동합니다.라이브 객체의 초기 세트는 알려진 각 Ruby 스레드 또는 등록된 각 전역 객체의 C 스택을 스캔하여 생성됩니다("알려진 라이브" 객체를 등록/등록 취소하는 C 함수가 있습니다).그런 다음 객체 X의 표시 기능은 X가 참조하는 각 객체에 대해 rb_gc_mark를 호출해야 합니다.즉, 당신이 하는 일은 정확히 당신이 해야 할 일이다.

그러나 나중에 알 수 있듯이 가능한 VALUE는 유효한 Ruby 객체가 아닙니다.그러나 나는 Qnil(즉,없음) 더 루비 같은 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top