Wie wollen Sie ein verpacktes C ++ Objekt freizugeben, wenn zugehörigen Javascript-Objekt Müll in V8 gesammelt?

StackOverflow https://stackoverflow.com/questions/173366

  •  05-07-2019
  •  | 
  •  

Frage

V8 in der Dokumentation erklärt wie ein Javascript-Objekt erstellen, die ein C ++ Objekt wickelt . Das Javascript-Objekt hält an einen Zeiger auf einen C ++ auf Objektinstanz. Meine Frage ist, sagen wir, Sie das Objekt auf dem Heap C ++ erstellen, wie können Sie eine Benachrichtigung erhalten, wenn das Javascript-Objekt von der gc gesammelt, so dass Sie die Heap zugewiesen C ++ Objekt befreien kann?

War es hilfreich?

Lösung

Der Trick ist, einen Persistent Griff (zweiten Punkt aus dem Linked-API-Referenz zu erzeugen. „Persistent Griffe auf einem Stapel gehalten werden, nicht und werden nur gelöscht, wenn Sie sie gezielt entfernen ... Verwenden Sie eine persistente, wenn Sie müssen für mehr als einen Funktionsaufruf einen Verweis auf ein Objekt halten, oder wenn der Griff Lebensdauern C entsprechen nicht ++ Bereiche. „), und rufen Sie MakeWeak() darauf, eine Rückruffunktion geben, die die notwendige Bereinigung tun wird (“ A persistent verarbeiten kann schwach, mit Persistent::MakeWeak gemacht werden, einen Rückruf vom Garbage Collector auszulösen, wenn die einzigen Verweise auf ein Objekt aus schwachen persistenten sind.“- das heißt, wenn alle‚normalen‘Griffe haben den Gültigkeitsbereich gegangen, und wenn die Garbage Collector ist über das Objekt löschen).

Die Persistent::MakeWeak Methodensignatur ist:

void MakeWeak(void* parameters, WeakReferenceCallback callback);

Wo WeakReferenceCallback als ein Zeiger-to-Funktion nimmt zwei Parameter definiert:

typedef void (*WeakReferenceCallback)(Persistent<Object> object,
                                      void* parameter);

Diese werden in der v8.h Header-Datei mit V8 als die öffentlichen API verteilt gefunden.

Sie wollen die Funktion Sie die MakeWeak Objektparameter zu bereinigen, Persistent<Object> übergeben, die an sie übergeben werden, wenn sie als Rückruf aufgerufen wird. Der void* parameter Parameter kann (oder die void* parameter kann auf eine C ++ Struktur zeigen, die die Objekte enthalten, die brauchen Reinigung) außer Acht gelassen werden:

void CleanupV8Point(Persistent<Object> object, void*)
{
    // do whatever cleanup on object that you're looking for
    object.destroyCppObjects();
}

Parameter<ObjectTemplate> my_obj(ObjectTemplate::New());

// when the Javascript part of my_obj is about to be collected
// we'll have V8 call CleanupV8Point(my_obj)
my_obj.MakeWeak(NULL, &CleanupV8Point);

Andere Tipps

In der Regel, wenn eine Garbage Collection Sprache Verweise auf Ressourcen außerhalb des Sprach-Engine halten kann (Dateien, Sockets oder in Ihrem Fall C ++ Objekte), sollten Sie eine ‚Schließen‘ Methode zur Verfügung stellen, dass die Ressource freizugeben so schnell wie möglich, keinen Punkt warten, bis der GC denkt, dass es sich lohnt, das Objekt zu zerstören.

es wird noch schlimmer, wenn IhrFormal C ++ Objektspeicher-hungrig ist und die Garbage Collection-Objekt ist nur ein Hinweis: Sie Tausende von Objekten zuordnen können, und die GC sieht nur ein paar KB winziger Objekte, nicht genug Sammlung auszulösen; während die C ++ Seite mit zig Megabyte veralteten Objekten zu kämpfen hat.

Haben alle Ihre Arbeit in einem gewissen geschlossenen Rahmen (von Objekt oder der Funktion). Dann können Sie sicher das C ++ Objekt entfernen, wenn Sie den Gültigkeitsbereich gehen. GC überprüft nicht, Zeiger auf die Existenz von spitzen Gegenständen.

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