Как освободить обернутый объект C ++, когда связанный объект Javascript собирается в V8? - PullRequest
24 голосов
/ 06 октября 2008

Документация V8 объясняет , как создать объект Javascript, который оборачивает объект C ++ . Объект Javascript держит указатель на экземпляр объекта C ++. Мой вопрос, скажем, вы создаете объект C ++ в куче, как вы можете получить уведомление, когда Gc-объект собирает объект Javascript, чтобы вы могли освободить выделенный объект C ++ в куче?

Ответы [ 3 ]

23 голосов
/ 07 октября 2008

Хитрость заключается в том, чтобы создать дескриптор Persistent (вторая точка маркера из ссылки на API-интерфейс, связанный с: "Persistent дескрипторы не хранятся в стеке и удаляются только тогда, когда вы специально удалили их. постоянный дескриптор, когда вам нужно сохранить ссылку на объект для более чем одного вызова функции, или когда время жизни дескриптора не соответствует областям действия C ++. ") и вызвать для него MakeWeak(), передав функцию обратного вызова, которая выполнит Необходимая очистка («Постоянный дескриптор можно сделать слабым, используя Persistent::MakeWeak, чтобы вызвать обратный вызов из сборщика мусора, когда единственные ссылки на объект - из слабых постоянных дескрипторов.» вышли из области видимости и когда сборщик мусора собирается удалить объект).

Подпись метода Persistent::MakeWeak:

void MakeWeak(void* parameters, WeakReferenceCallback callback);

Где WeakReferenceCallback определяется как указатель на функцию, принимающая два параметра:

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

Они находятся в заголовочном файле v8.h, распространяемом с V8 в качестве общедоступного API.

Вы бы хотели, чтобы функция, которую вы передали MakeWeak, очистила параметр объекта Persistent<Object>, который будет передан ему при вызове в качестве обратного вызова. Параметр void* parameter можно игнорировать (или void* parameter может указывать на структуру C ++, которая содержит объекты, которые необходимо очистить):

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);
0 голосов
/ 07 октября 2008

Делайте всю свою работу в некоторой замкнутой области (объекта или функции). Затем вы можете безопасно удалить объект C ++, когда вы вышли из области видимости. GC не проверяет указатели на наличие указанных объектов.

0 голосов
/ 06 октября 2008

В общем, если язык, на котором собирается мусор, может содержать ссылки на ресурсы вне языкового движка (файлы, сокеты или, в вашем случае, объекты C ++), вы должны предоставить метод close для освобождения этого ресурса как можно скорее, нет Дождитесь, пока сборщик мусора не решит, что стоит уничтожить ваш объект.

становится еще хуже, если ваш объект C ++ требует много памяти, а объект сбора мусора является просто ссылкой: вы можете выделить тысячи объектов, а сборщик мусора видит только несколько кбайт крошечных объектов, которых недостаточно для запуска сбора; в то время как сторона C ++ борется с десятками мегабайт устаревших объектов.

...