【问题标题】:Should we use Async / Await or Then Closures for avoiding memory leak?我们应该使用 Async / Await 还是 Then Closures 来避免内存泄漏?
【发布时间】:2018-10-25 12:01:04
【问题描述】:

我有一个使用太多内存的 NodeJS 应用程序。我们正在尝试追踪问题的根源。

所以我读到闭包不利于内存使用。垃圾收集器很难释放闭包使用的内存。

我们的代码有很多部分都使用了这样的 Promise:

thenableFunction().then(() => {...}).then(() => {...}).catch(() => {...});

所以在阅读了关于闭包的内容后,我想将所有内容重构为

try{
    let result = await thenableFunction();
    ...
}catch(e){...}

我现在想知道我们是否会从这种重构中受益,或者它毕竟没有任何区别。

你怎么看?你知道有什么好的链接可以解释这一点吗?

谢谢

【问题讨论】:

  • 我认为这不会影响内存使用。
  • 我有什么found
  • "我读到闭包不利于内存使用。" - 你从哪里读到的?!
  • 我会让他为自己说话,但是有一些报告的案例是有些模糊的重复/递归关闭模式可能会导致内存泄漏。 (请参阅下面我的答案中的链接)。
  • @Doug 我希望你没有计算 IE6 案例(RIP!)。而关于 Meteor 案例,这是一个与哑 GC 一起玩的非常模糊的边缘案例。但是我们不能从这个例子中概括出“闭包是不好的”。否则,每个数据结构都不利于内存使用!链接列表很糟糕!说真的,可以用(更不显眼的)async/await 代码重现这种情况。

标签: node.js memory-leaks promise async-await


【解决方案1】:

await 实际上是您要替换的代码的语法糖(好吧,除了代码块之后的任何代码也有效地被拉入 then 子句 - 这就是 @ 987654324@ 关键字有效地阻止执行,直到 Promise 解决)。所以这个重构应该不会真正影响内存消耗。

问题的具体答案取决于两个问题。首先,重写是否避免了闭包(在原始代码中是明确的),其次(假设第一个答案是肯定的),垃圾收集器是否会像 Promise 正在做的事情一样失败 GC 闭包(如果它没有隐式创建闭包)。

我很确定第一个问题的答案是否定的——await Promise 确实在创建隐式闭包。所以我认为你一开始并没有避开它们。

关于第二个问题,根据我的阅读,听起来闭包只会在某些特定情况下导致奇怪的垃圾收集问题(即泄漏):

https://www.ibm.com/developerworks/library/wa-use-javascript-closures-efficiently/index.html

https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

因此,除非您对闭包的使用与其中一些模式相匹配,否则我认为即使您的 Promise 没有隐式创建相同的闭包,您仍然会遇到类似的 GC 行为。

【讨论】:

  • 但是当不使用闭包时,垃圾收集器是否更容易识别要从内存中清除的内容?!
  • @VictorFerreira 你不能不关闭范围内的变量。不管你怎么写你的异步函数。
猜你喜欢
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 2012-10-22
  • 2013-01-15
  • 2018-04-08
  • 2013-06-24
相关资源
最近更新 更多