【问题标题】:Correctly disposing Persistent<ArrayBuffer>正确处理 Persistent<ArrayBuffer>
【发布时间】:2016-07-15 19:48:23
【问题描述】:

我得到了非常简单的代码:

struct Dyn {
 float *ptr;
 int n;
};


void setWeakFunction1(const WeakCallbackInfo<Dyn> &data) {
}
void setWeakFunction(const WeakCallbackInfo<Dyn> &data) {
 auto *v = data.GetParameter();
 data.SetSecondPassCallback(setWeakFunction1);
 std::cout << v->n << " Collector\n";
 delete[] v->ptr;
 delete v;

}

void getIndex(const FunctionCallbackInfo<Value> &args) {
  Dyn *d = new Dyn;
  float *ptr = new float[amount];
  for (size_t i = 0; i < amount; ++i) {
    ptr[i] = i + 2;
  }

  auto isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
  Local<ArrayBuffer> ab =
      ArrayBuffer::New(isolate, ptr, amount * sizeof(float));
  Persistent<ArrayBuffer> pab(isolate, ab);
  pab.SetWeak(d, setWeakFunction, WeakCallbackType::kInternalFields);
  pab.MarkIndependent();
  args.GetReturnValue().Set(ab);
}

void RegisterModule(Local<Object> exports, Local<Object>) {
 auto isolate = Isolate::GetCurrent();
 exports->Set(String::NewFromUtf8(isolate, "getIndex"),
           FunctionTemplate::New(isolate, getIndex)->GetFunction());
}

NODE_MODULE(commander, RegisterModule)

这段代码对我来说有点尴尬。

由于有一个计数器,我预计,我创建的每个 Persistence 存储都会调用 setWeakFunction。当浮点数少于 10000 时,它会调用每个持久单元。但是当浮点数的大小变为100 000 时,它不会尝试处理任何对象,直到有 1Gb 的内存被吃掉,然后它会不断地删除,但会留下 2-3 个对象。

我有一个想法,垃圾收集器为一堆对象调用一次WeakCallback,但没有找到信息,证实了这一点。

更糟糕的是,我从未见过任何针对 1000 000 浮点数组的垃圾收集调用。

如何正确处理这些数组?

【问题讨论】:

  • 它看起来像笨拙的代码。 c++中没有垃圾回收,也不需要。
  • @RichardHodges,你提到v8arraybuffer 标签了吗?

标签: c++ v8 arraybuffer


【解决方案1】:

让我尝试修复上面的代码:

struct Dyn {
    Persistent<ArrayBuffer> pab;
    float *ptr;
    int n;
};

void setWeakFunction(const WeakCallbackInfo<Dyn> &data) {
    auto *v = data.GetParameter();
    std::cout << v->n << " Collector\n";
    v->pab.Reset();
    delete[] v->ptr;
    delete v;

}

void getIndex(const FunctionCallbackInfo<Value> &args) {
    Dyn *d = new Dyn;
    float *ptr = new float[amount];
    for (size_t i = 0; i < amount; ++i) {
        ptr[i] = i + 2;
    }

    auto isolate = args.GetIsolate();
    HandleScope scope(isolate);
    Local<ArrayBuffer> ab =
        ArrayBuffer::New(isolate, ptr, amount * sizeof(float), ArrayBufferCreationMode::kExternalized);
    d->pab.Reset(isolate, ab);
    d->pab.SetWeak(d, setWeakFunction, WeakCallbackType::kParameter);
    d->pab.MarkIndependent();
    args.GetReturnValue().Set(ab);
}

void RegisterModule(Local<Object> exports, Local<Object>) {
    auto isolate = Isolate::GetCurrent();
    exports->Set(String::NewFromUtf8(isolate, "getIndex"),
        FunctionTemplate::New(isolate, getIndex)->GetFunction());
}

NODE_MODULE(commander, RegisterModule)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 2015-09-18
    相关资源
    最近更新 更多