【问题标题】:Node (memory leak, v8 snapshot) - is it bad practice to use a connection promise?节点(内存泄漏,v8 快照)- 使用连接承诺是不好的做法吗?
【发布时间】:2014-10-31 21:46:42
【问题描述】:

我不希望 DB 请求在连接前意外运行,因此 connect 方法返回一个 promise,并且每个 DB 方法都使用 connectPromise.then()

似乎我的应用程序正在泄漏内存,所以我想知道这是否是原因。 v8 堆内存快照中的头号违规者标题为sql,其中包含很多来自 bluebird 承诺和域的内容。我真的不知道该怎么做,但我想到了一个连接承诺。

编辑:我已经确认问题的根源确实是我遵守续集承诺的做法。为了测试,我尝试每 30 秒刷新一次该承诺,我的应用程序停止收集越来越多的内存。

我开了一个issue in sequelize

【问题讨论】:

  • 与其他 Promise 相比,Bluebird Promise 的大小很小(与原生 Promise 相比也是如此)。也就是说,泄漏总是可能的,并且没有代码是错误安全的。您是否有可能保留对您创建的所有承诺的引用?
  • 在v8快照的最顶部,有一个叫做“sql”的对象,不知道它的名字是怎么来的。它所拥有的只是对错误、域和承诺的引用。
  • 这听起来可能很奇怪 - 但您能否将 Bluebird 更新到最新版本,看看问题是否消失?
  • 我不确定是不是这样,但是 v8 快照将我带到了这个文件,它提到了事件和承诺,并在关键“sql”下的承诺内部存储了东西 - sequelize promise code
  • Sequelize dev here,肯定存在sequelize 的漏洞,因为当我们主要转向promises 时,我们想为sql 事件维护BC。我们将在 GH 问题上寻找一个可能的解决方案,它肯定可以处理长期解决的承诺。

标签: node.js memory-leaks garbage-collection sequelize.js bluebird


【解决方案1】:

假设您正在编写服务器,为什么不在侦听端口之前建立数据库连接?

db.connect().then(function(){
     server.listen(function(){

     });
});

我并不是说 Sequelize 的问题不存在,但我认为最好不要在每次发出数据库请求时都调用 connect().then()

这种类型的模式有很多地方,我认为这不是其中之一。

Bluebird 似乎不能很好地与domains 配合使用,这就是发生内存泄漏的地方。 Bluebird 是我所知道的唯一一个尝试在 Node.js 中正确传播域的 Promise 库。

【讨论】:

  • 保持连接的承诺,我不会重复调用连接。
  • 对不起,我没有关注,如果您添加更多代码我可以尝试
  • 在顶部,我有类似var connectPromise = db.connect() 的内容,然后每个数据获取方法都使用该承诺,例如function find(query) { return connectPromise.then(db.find.bind(db, query)) }。这只是我现在编的一个例子,不是代码的样子,问题已经解决了一段时间:)
  • 是的,我认为 np 是有道理的
猜你喜欢
  • 2022-01-06
  • 2020-01-03
  • 2013-02-08
  • 2018-04-28
  • 2019-02-24
  • 2017-05-06
  • 2013-12-02
  • 2015-10-18
相关资源
最近更新 更多