¿Cómo se libera un objeto C++ envuelto cuando el objeto Javascript asociado es basura recolectada en V8?


La documentación de V8 explica cómo crear un objeto Javascript que envuelva un objeto C++ . El objeto Javascript mantiene un puntero a una instancia de objeto C++. Mi pregunta es, digamos que crea el objeto C++ en el montón, ¿cómo puede obtener una notificación cuando el objeto Javascript es recopilado por el gc, para que pueda liberar el objeto C++ asignado al montón?

Author: postfuturist, 2008-10-06

3 answers

El truco es crear un manejador Persistent (segundo punto de la referencia de la API vinculada: "Persistent los manejadores no se mantienen en una pila y solo se eliminan cuando los eliminas específicamente. ... Utilice un identificador persistente cuando necesite mantener una referencia a un objeto para más de una llamada a una función, o cuando los tiempos de vida del identificador no se correspondan con los ámbitos de C++."), y llame a MakeWeak() en él, pasando una función de devolución de llamada que hará la limpieza necesaria ("Un controlador persistente se puede hacer débil, utilizando Persistent::MakeWeak, para activar una devolución de llamada desde el recolector de basura cuando las únicas referencias a un objeto son de manejadores persistentes débiles."that es decir, cuando todos los controladores "regulares" han salido del ámbito y cuando el recolector de basura está a punto de eliminar el objeto).

La firma del método Persistent::MakeWeak es:

void MakeWeak(void* parameters, WeakReferenceCallback callback);

Donde WeakReferenceCallback se define como un puntero a la función tomando dos parámetros:

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

Estos se encuentran en el v8.h archivo de cabecera distribuido con V8 como el público API.

Usted querrá que la función que pase a MakeWeak limpie el parámetro objeto Persistent<Object> que se le pasará cuando se le llame como una devolución de llamada. El parámetro void* parameter puede ser ignorado (o el void* parameter puede apuntar a una estructura C++ que contiene los objetos que necesitan limpieza):

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);
 22
Author: Max Lybbert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-23 08:36:54

En general, si un lenguaje recopilado puede contener referencias a recursos fuera del motor del lenguaje (archivos, sockets, o en su caso objetos C++), debe proporcionar un método 'close' para liberar ese recurso LO antes posible, sin esperar hasta que el GC piense que vale la pena destruir su objeto.

Se pone peor si su objeto C++ está hambriento de memoria y el objeto recogido en la basura es solo una referencia: puede asignar miles de objetos, y el GC solo ve unos pocos KB de objetos diminutos, no suficientes para activar la colección; mientras que el lado de C++ está luchando con decenas de megabytes de objetos obsoletos.

 0
Author: Javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 18:12:48

Haga todo su trabajo en algún ámbito cerrado (de objeto o función). A continuación, puede eliminar de forma segura el objeto C++ cuando se salió del ámbito. GC no comprueba punteros para la existencia de objetos puntiagudos.

 0
Author: Thevs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 20:38:24