Gol*_*den 50 closures memory-leaks node.js
您经常在网上看到使用闭包是JavaScript中的大量内存泄漏源.大多数时候,这些文章都涉及混合脚本代码和DOM事件,其中脚本指向DOM,反之亦然.
我知道闭包可能是一个问题.
但是Node.js怎么样?在这里,我们自然没有DOM - 所以没有机会像浏览器一样有内存泄漏副作用.
关闭可能还有哪些其他问题?任何人都可以详细说明或指点我这方面的好教程吗?
请注意,此问题明确针对Node.js,而不是浏览器.
Rus*_*bot 36
这个问题询问类似的事情.基本上,我们的想法是,如果在回调中使用闭包,则应在完成后"取消订阅"回调,以便GC知道无法再次调用它.这对我来说很有意义; 如果你有一个关闭只是等待被调用,那么GC将很难知道你已经完成了它.通过从回调机制手动删除闭包,它将变为未引用并可用于收集.
此外,Mozilla发表了一篇关于在Node.js代码中查找内存泄漏的精彩文章.我假设如果你尝试他们的一些策略,你可以找到代表泄漏行为的部分代码.最佳实践很好,但我认为了解您的程序需求更有帮助,并根据您可以凭经验观察的内容提出一些个性化的最佳实践.
以下是Mozilla文章的快速摘录:
- Jimb Esser
node-mtrace,它使用GCCmtrace实用程序来分析堆使用情况.- Dave Pacheco
node-heap-dump拍摄了V8堆的快照,并在一个巨大的JSON文件中将整个序列序列化.它包括用于遍历和调查JavaScript中生成的快照的工具.- 丹尼科茨的
v8-profiler和node-inspector为V8探查,并使用WebKit网络检查节点调试接口提供节点绑定.- 菲利克斯·格纳斯(Felix Gnass)同样禁用了保留者图表
- FelixGeisendörfer的节点内存泄漏教程是关于如何使用
v8-profiler和的简短而精彩的解释node-debugger,并且目前是大多数Node.js内存泄漏调试的最新技术.- Joyent的SmartOS平台,为您调试Node.js内存泄漏提供了大量工具
这个问题的答案基本上说你可以通过分配null闭包变量来帮助GC .
var closureVar = {};
doWork(function callback() {
var data = closureVar.usefulData;
// Do a bunch of work
closureVar = null;
});
Run Code Online (Sandbox Code Playgroud)
函数内部声明的任何变量在函数返回时都会消失,但在其他闭包中使用的变量除外.在这个例子中,closureVar必须在内存中直到callback()被调用,但谁知道什么时候会发生?调用回调后,可以通过将闭包变量设置为null来提示GC.
免责声明:正如您从下面的评论中看到的,有一些SO用户说这些信息已经过时且对Node.js无关紧要.我还没有明确的答案; 我只是发布了我在网上发现的内容.
bor*_*kur 10
你可以在David Glasser的博客文章中找到一个很好的例子和解释.
嗯,这是(我添加了一些评论):
var theThing = null;
var cnt = 0; // helps us to differentiate the leaked objects in the debugger
var replaceThing = function () {
var originalThing = theThing;
var unused = function () {
if (originalThing) // originalThing is used in the closure and hence ends up in the lexical environment shared by all closures in that scope
console.log("hi");
};
// originalThing = null; // <- nulling originalThing here tells V8 gc to collect it
theThing = {
longStr: (++cnt) + '_' + (new Array(1000000).join('*')),
someMethod: function () { // if not nulled, original thing is now attached to someMethod -> <function scope> -> Closure
console.log(someMessage);
}
};
};
setInterval(replaceThing, 1000);
Run Code Online (Sandbox Code Playgroud)
请originalThing在Chrome开发工具(时间线选项卡,内存视图,点击记录)中使用和不使用归零进行试用.请注意,上面的示例适用于浏览器和Node.js环境.
还要特别感谢Vyacheslav Egorov.
| 归档时间: |
|
| 查看次数: |
25253 次 |
| 最近记录: |