v8(Node.js)迭代器处理堆积

时间:2018-06-27 20:30:13

标签: javascript c++ node.js v8

我有一个iterator defined in C++。典型迭代的代码路径基本上是:

NAN_METHOD(SharedMap::next) {
  auto obj = Nan::New<v8::Object>();
  info.GetReturnValue().Set(obj);  
  // ...
  auto arr = Nan::New<v8::Array>();
  arr->Set(0, Nan::New<v8::String>("key example").ToLocalChecked());  
  arr->Set(1, Nan::New<v8::String>("value example").ToLocalChecked());
  Nan::Set(obj, Nan::New<v8::String>("value").ToLocalChecked(), arr);
}

我可以在JS端使用以下方法进行迭代:

for (let [key, value] of iteratorObject) {
  console.log(`${key}: ${value}`)
}

如果我使用memwatch.HeapDiff()检查此循环的每10000次迭代,则会看到change.details如下:

"details": [
  {
    "what": "Array",
    "size_bytes": 810344,
    "size": "791.35 kb",
    "+": 20151,
    "-": 85
  },
  {
    "what": "Object",
    "size_bytes": 399368,
    "size": "390.01 kb",
    "+": 10001,
    "-": 12
  },
  {
    "what": "String",
    "size_bytes": -144,
    "size": "-144 bytes",
    "+": 13,
    "-": 27
  },
  {
    "what": "TickObject",
    "size_bytes": 560056,
    "size": "546.93 kb",
    "+": 10001,
    "-": 0
  }
}

这似乎意味着在每次循环迭代中有两个数组分配,一个对象分配和一个TickObject分配。我不确定为什么没有匹配数量的字符串分配。我也不确定第二个数组分配来自哪里(可能来自解构吗?)。

如果我让该循环运行几百万个周期,我最终将用光内存(JS因堆错误而崩溃)。

当GC在该循环中运行时,如何确保可以回收为该循环的先前迭代所做的分配?

0 个答案:

没有答案