【问题标题】:v8 WeakCallback never gets calledv8 WeakCallback 永远不会被调用
【发布时间】:2014-06-08 14:47:26
【问题描述】:

我知道这个问题很老,但我找到的所有答案都不起作用并且已经过时了。 但这是我的代码:

void Destroyed(const v8::WeakCallbackData<v8::Object, int>& info)
{
    std::cout << "d: " << *info.GetParameter() << std::endl;
}

std::vector<v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>>> persistent;
int i = 0;

void Constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::HandleScope scope(v8::Isolate::GetCurrent());

    v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>> per;
    per = v8::Persistent<v8::Object>(v8::Isolate::GetCurrent(), info.This());

    per.SetWeak<int>(new int(i), Destroyed);

    persistent.push_back(per);

    ++i;

    while(!v8::V8::IdleNotification()) {}
}

void TestV8()
{
    v8::Isolate* isolate = v8::Isolate::New();

    v8::Isolate::Scope isolateScope(isolate);

    v8::HandleScope scope(isolate);

    v8::Local<v8::Context> context = v8::Context::New(isolate);

    v8::Context::Scope contextScope(context);

    v8::Local<v8::FunctionTemplate> temp = v8::FunctionTemplate::New(isolate, Constructor);

    context->Global()->Set(v8::String::NewFromUtf8(isolate, "Object"), temp->GetFunction());

    v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "while(true) {new Object();}");

    v8::Local<v8::Script> script = v8::Script::Compile(source);

    v8::Local<v8::Value> result = script->Run();

    std::cout << *v8::String::Utf8Value(result) << std::endl;
}

如果我不将持久性添加到向量中,则内存不会增加。 但是 Destroyed 永远不会被调用,我似乎无法弄清楚出了什么问题,请帮忙:)

【问题讨论】:

    标签: c++ v8 persistent


    【解决方案1】:

    我在下面解决了它是工作代码。显然 Persistent 复制构造函数没有将其复制到弱引用的位置,因此将其转换为指针解决了它。

    std::vector<v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>>*> persistent;
    int i = 0;
    
    void Destroyed(const v8::WeakCallbackData<v8::Object, int>& info)
    {
        std::cout << "d: " << *info.GetParameter() << std::endl;
    
        persistent[*info.GetParameter()]->Reset();
    }
    
    void Constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
    {
        v8::HandleScope scope(v8::Isolate::GetCurrent());
    
        v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>>* per = new v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>>(v8::Isolate::GetCurrent(), info.This());
        per->SetWeak<int>(new int(i), Destroyed);
        persistent.push_back(per);
    
        ++i;
    
        while(!v8::V8::IdleNotification()) {}
    }
    
    void TestV8()
    {
        v8::Isolate* isolate = v8::Isolate::New();
        v8::Isolate::Scope isolateScope(isolate);
    
        v8::HandleScope scope(isolate);
    
        v8::Local<v8::Context> context = v8::Context::New(isolate);
        v8::Context::Scope contextScope(context);
    
        v8::Local<v8::FunctionTemplate> temp = v8::FunctionTemplate::New(isolate, Constructor);
    
        context->Global()->Set(v8::String::NewFromUtf8(isolate, "Object"), temp->GetFunction());
    
        v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "while(true) {new Object();}");
        v8::Local<v8::Script> script = v8::Script::Compile(source);
        v8::Local<v8::Value> result = script->Run();
    
        std::cout << *v8::String::Utf8Value(result) << std::endl;
    }
    

    【讨论】:

    • 这里真正的答案是“使用v8::Global”。 v8::CopyablePersistentTraits 非常糟糕
    【解决方案2】:

    您检查过SetWeakdocumentation 吗?它明确指出以下内容:

    /**
     *  Install a finalization callback on this object.
     *  NOTE: There is no guarantee as to *when* or even *if* the callback is
     *  invoked. The invocation is performed solely on a best effort basis.
     *  As always, GC-based finalization should *not* be relied upon for any
     *  critical form of resource management!
     */
    template<typename P>
    V8_INLINE void SetWeak(
        P* parameter,
        typename WeakCallbackData<T, P>::Callback callback);
    

    【讨论】:

    • 是的,我有,但我不相信它会错过其中的 2GB。另外,当我没有为它们创建任何持久句柄时,它们会收集垃圾。那么当他们得到一个弱引用时,他们为什么不这样做呢?
    • 据我所见,您将每个创建的对象的句柄存储到您的 persistent 向量中,这显然使所有对象都处于活动状态,因此它们都无法被收集。
    • 是的,但我将它们设为弱,所以应该收集它们对吗?
    • 我似乎发现了 per.IsWeak() 返回 1 的问题,但如果我键入 persistent.back().IsWeak() 它返回 0。将向量更改为包含指针它适用于一个至少。然后 (state() != NEAR_DEATH) 但嘿更近一步 :)
    猜你喜欢
    • 2012-10-27
    • 2013-10-12
    • 2012-03-27
    • 2013-08-29
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2015-10-15
    相关资源
    最近更新 更多