0

我有一个使用 Nan 库的 c++ 节点添加。我有一个需要返回缓冲区的函数。最简单的版本如下(根据注释编辑代码):

NAN_METHOD(Test) {
    char * retVal = (char*)malloc(100 * sizeof(char));
    info.GetReturnValue().Set(Nan::NewBuffer(retVal, 100 *sizeof(char)).ToLocalChecked());
}

联合只是用作重新解释字节的简单方法。根据文档, Nan::NewBuffer 承担了内存的所有权,因此无需手动释放内存。但是,当我运行使用此功能的节点代码时,我的内存猛增,即使我通过强制垃圾收集器运行global.gc();节点代码产生错误也非常简单:

const addon = require("addon");
for (let i = 0; i < 100000000; i++) {
  if(i % (1000000) === 0){
    console.log(i);
    try {
      global.gc();
    } catch (e) {
      console.log("error garbage collecting");
      process.exit();
    }
  }
  const buf = addon.Test();
}

任何帮助,将不胜感激。

4

2 回答 2

1

经过大量的实验和研究,我发现这篇文章在此处输入链接描述基本上表明释放传递给 Nan::NewBuffer 的内存的承诺只是一个谎言。使用 Nan::CopyBuffer 而不是 Nan::NewBuffer 以 memcpy 为代价解决了该问题。所以基本上,答案是 Nan::NewBuffer 坏了,你不应该使用它。请改用 Nan::CopyBuffer。

于 2021-01-20T15:53:22.947 回答
0

在 IT 中,我们倾向于将文档中的谎言称为错误。

这个问题一直是 Node.js 问题的主题 - https://github.com/nodejs/node/issues/40936

答案是底层缓冲区的释放发生在 JSSetImmediate处理程序的 C++ 等效项中,如果您的代码是完全同步的 - 这是您的情况 - 缓冲区在程序结束之前不会被释放。

您正确地发现Nan::CopyBuffer不存在此问题。

唉,这不容易解决,因为 Node.js 不知道这个缓冲区是如何分配的,也不能从垃圾收集器上下文中调用它的回调。

如果您正在使用Nan::NewBuffer我还建议查看此问题:https ://github.com/nodejs/node/issues/40926 ,其中讨论了另一个密切相关的陷阱。

于 2021-11-25T23:42:48.387 回答