最近被v875的gc搞蒙了。做个总结。
1,v8::Persistent<T>的机制改了。如果用SetWeak设置了回收回调,那么如果在UnifiedHeapController::AdvanceTracing里不RegisterEmbedderReference的话,js如果也没引用,就会触发这个回收回调。57好像不会有这问题。这个变动,导致了一系列问题。
例如document.getElementById("test").addEventListener这种方式添加的监听器,就直接被回收了。
在57版本里,是有个ScriptWrappableVisitor::AdvanceTracing -》
Element::traceWrappers-》
EventTargScriptWrappableVisitor::pushToMarkingDeque
的trace wrap机制。这个会保证监听器不回收。
我一开始解决这问题,是想在VisitPersistentHandle里把所有v8::Persistent<T>都不回收(通过设置v8::Persistent<T>::SetWrapperClassId 的方式来识别)
后来发现ScriptState里的v8::Context也不回收了。
另外还有个小插曲,我发现v8::Persistent被析构还不行,得手动调用SetWeak、ClearWeak、Reset才行。
所以现在我的思路是在遍历node的时候,通过addReferencesForNodeWithEventListeners把这个node下面的监听器调用一下RegisterV8References。而刚才我还发现,49原来是在addReferencesForNodeWithEventListeners里调用isolate->SetReference导致引用的。