Frage

Ich habe einen Matrixtyp, der a enthält void* Array, das ein Array von Objekten darstellt (die alle von einem Typ in einer bestimmten Matrix sind, z. B. alle C-Ganzzahlen, alle Floats, Doubles, eine Vielzahl von Strukturen oder möglicherweise sogar alle Ruby). VALUES).

Speicherzuweisung und Speicherbereinigung scheinen ordnungsgemäß zu funktionieren, bis ich versuche, eine Matrix zu erstellen VALUES.

Ich habe die folgende Markierungsfunktion definiert:

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)));
}

Es erfolgt also nur eine Markierung, wenn es sich tatsächlich um eine handelt VALUE Matrix – andernfalls NULL wird weitergeleitet an Data_Wrap_Struct für die Markierungsfunktion.

Aber ich erhalte einen Segfault, wenn ich einige davon teste VALUE Matrixfunktionen (siehe Kern).

Insbesondere scheint es beim ersten Versuch, eine Ruby-Methode für das allererste Objekt in aufzurufen, zu einem Segfault zu kommen VALUE* Array:

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 ist eine globale Definition in meinem Init funktionieren als rb_intern("*").

Es ist möglich, dass es sich hierbei nicht um ein Garbage-Collection-Problem handelt, aber der GC ist der Teil von Ruby, den ich am wenigsten verstehe – und mein Segfault ist auch fast identisch damit diese Spur, was der Poster dem GC zuschreibt.

Also meine Fragen:

  1. Wenn es sich um den GC handelt, wie markiert man dann ein Array von? VALUES?

  2. Wenn es nicht der GC ist, wie kann ich diesen Fehlertyp diagnostizieren?So etwas habe ich noch nie gesehen.

BEARBEITEN:

Es stellt sich heraus, dass dies ein Beispiel für einen Fehler bei der Initialisierung ist VALUEwurde in C erstellt.

Mit anderen Worten: Stellen Sie sicher, dass Sie dies tun *(VALUE*)a = INT2FIX(0) bevor Sie versuchen, darauf zuzugreifen a.

Ich halte die Frage immer noch für relevant.Ich habe es nicht geschafft, wirklich gute Beispiele für die Markierung für die Clean-and-Sweep-Garbage Collection zu finden, weder auf StackOverflow noch anderswo.Wenn Sie ein solches Beispiel und/oder eine solche Erklärung liefern können, markiere ich dies als richtige Antwort auf diese Frage.

War es hilfreich?

Lösung

Rubys Mark-and-Sweep-GC arbeitet in zwei Stufen.

Die erste Stufe markiert lebende Objekte.Es funktioniert rekursiv, indem es die Markierungsfunktion jedes bekannten „lebenden Objekts“ aufruft.Der anfängliche Satz an Live-Objekten wird durch Scannen des C-Stacks jedes bekannten Ruby-Threads oder jedes registrierten globalen Objekts erstellt (es gibt eine C-Funktion zum Registrieren/Abmelden von „bekannten Live“-Objekten).Die Markierungsfunktion von Objekt X sollte dann rb_gc_mark für jedes Objekt aufrufen, auf das X verweist.Mit anderen Worten: Was Sie tun, ist genau das, was Sie tun sollten.

Allerdings ist, wie Sie später bemerkt haben, nicht jeder mögliche VALUE ein gültiges Ruby-Objekt.Ich glaube jedoch, dass die Initialisierung mit Qnil (d. h.Null) wäre eher rubinrot.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top