V8의 설명서에서 how to create a Javascript object that wraps a C++ object을 설명합니다. Javascript 객체는 C++ 객체 인스턴스에 대한 포인터를 보유합니다. 제 질문은, 힙에 C++ 객체를 생성한다고 가정 해 봅시다. gc가 Javascript 객체를 수집 할 때 통보를받을 수 있으므로 할당 된 C++ 객체를 해제 할 수 있습니까?V8에서 연결된 자바 스크립트 객체가 가비지 수집 될 때 어떻게 래핑 된 C++ 객체를 해제합니까?
답변
트릭은 Persistent
핸들 (링크 된 API 참조에서 두 번째 글 머리 기호 : "Persistent
핸들을 스택에 보관하지 않고 특별히 제거 할 때만 삭제됩니다. ... 영구적 인 핸들을 사용하십시오 둘 이상의 함수 호출에 대한 객체에 대한 참조를 유지해야하거나 핸들 수명이 C++ 범위와 일치하지 않을 때 "), MakeWeak()
을 호출하고 필요한 정리 작업을 수행 할 콜백 함수 ("A 영구적 인 핸들은 약한 지속 핸들에서 객체를 참조하는 경우 가비지 콜렉터로부터 콜백을 트리거하기 위해 Persistent::MakeWeak
을 사용하여 약하게 만들 수 있습니다. "즉 모든"일반 "핸들이 범위를 벗어 났을 때 그리고 언제 가비지 컬렉터가 개체를 삭제하려고합니다.)
Persistent::MakeWeak
메소드 서명은 다음과 같습니다
WeakReferenceCallback
가 함수 포인터는 두 개의 매개 변수 복용으로 정의된다
void MakeWeak(void* parameters, WeakReferenceCallback callback);
:
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);
일반적으로 가비지 수집 언어가 언어 엔진 (파일, 소켓 또는 C++ 객체) 외부의 리소스에 대한 참조를 보유 할 수있는 경우 해당 리소스를 가능한 빨리 릴리스하는 '닫기'메소드를 제공해야합니다. GC가 개체를 파괴하는 것이 가치 있다고 생각할 때까지 기다리지 않아도됩니다.
C++ 개체가 메모리를 많이 차지하고 가비지 수집 개체가 참조 인 경우 악성이 발생합니다. 수천 개의 개체를 할당 할 수 있으며 GC는 수집 작업을 트리거 할만큼 작은 개체 만 볼 수 있습니다 ; C++ 측은 수십 메가 바이트의 오래된 개체로 고생하고 있습니다.
... 당신이 할 수있는이 방법 V8에 당신의 물건이 배가 고팠다 고 말해주세요 :-) – nalply
모든 작업을 (개체 또는 기능의) 일부 닫힌 범위에서 수행하십시오. 그러면 범위를 벗어 났을 때 C++ 개체를 안전하게 제거 할 수 있습니다. GC는 뾰족한 객체가 있는지 포인터를 확인하지 않습니다.
로컬
@ xaxxon : V8 Javascript 엔진에 대한 경험이 없다는 것을 처음으로 인정할 것입니다. (필자는 6 년 전에이 질문에 대한 답을 찾을 수있었습니다.) ** ** 귀하의 질문에 대한 답변은 https://developers.google.com/v8/embed의 예입니다.csw = 1 # 역동적이지만 질문 할 가치가있는 질문이있을 수도 있습니다. –
감사합니다. 나는 결국 그것을 알아 냈다. https://code.google.com/p/chromium/codesearch#chromium/src/v8/src/d8.cc&l=1064 1400 줄 주변 시작 – xaxxon