【问题标题】:Node Add-on Nan::NewBuffer Causes Memory Leak节点插件 Nan::NewBuffer 导致内存泄漏
【发布时间】:2021-04-24 02:49:56
【问题描述】:

我有一个使用 Nan 库的 c++ 节点插件。我有一个需要返回缓冲区的函数。最简单的版本如下(代码按照cmets编辑):

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

联合只是用作重新解释字节的简单方法。根据documentation,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();
}

任何帮助将不胜感激。

【问题讨论】:

  • (1) gc 例程调用free 而不是delete ("...数据将通过调用free()..." ); (2) 通过union 给指针起别名是Undefined Behaviour; (3) 即使是名为delete 的 gc 例程,它也会尝试删除别名指针 UB。
  • @RichardCritten 谢谢。我将如何达到预期的结果?重新解释演员阵容会起作用吗?删除与免费的观点是正确的,但在这里并没有伤害到我,因为没有什么可以破坏的。
  • 如果你不将new/deletemalloc/free 配对,那么代码就在UB 领域,尝试推理它是没有意义的。
  • @RichardCritten 好的,所以解决方案是使用 malloc 而不是 new。我会试试的。
  • @RichardCritten 相同的泄漏,更改为 malloc 后(在问题中编辑)

标签: c++ node.js memory-leaks v8 node-addon-api


【解决方案1】:

经过大量的实验和研究,我发现了这个帖子enter link description here,它基本上说明了释放传递给 Nan::NewBuffer 的内存的承诺只是一个谎言。使用 Nan::CopyBuffer 而不是 Nan::NewBuffer 以 memcpy 为代价解决了该问题。所以基本上,答案是 Nan::NewBuffer 坏了,你不应该使用它。请改用 Nan::CopyBuffer。

【讨论】:

    【解决方案2】:

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

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

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

    您正确地发现Nan::CopyBuffer 没有遇到这个问题。

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

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

    【讨论】:

    • ooof,在软件工程中,我们倾向于避免使用 IT 一词作为自我描述;)
    猜你喜欢
    • 2015-07-06
    • 2014-06-07
    • 2013-11-20
    • 2011-10-28
    • 2016-01-18
    • 2012-12-13
    • 1970-01-01
    • 2011-01-08
    • 2011-02-01
    相关资源
    最近更新 更多