JavaScript中的内存泄漏和关闭 - 什么时候和为什么? [英] Memory leaks and closures in JavaScript - when and why?
问题描述
你经常在网上看到,使用闭包是JavaScript中的大量内存泄漏源。大多数时候,这些文章涉及混合脚本代码和DOM事件,其中脚本指向DOM,反之亦然。
You quite often read on the web that using closures is a massive source of memory leaks in JavaScript. Most of the times these articles refer to mixing script code and DOM events, where the script points to the DOM and vice-versa.
我理解闭包可能是一个问题
I understand that closures can be a problem there.
但是Node.js呢?在这里,我们自然没有DOM - 所以没有机会像浏览器一样有内存泄漏的副作用。
But what about Node.js? Here, we naturally don't have a DOM - so there is no chance to have memory leaking side effects as in browsers.
闭包还有什么其他问题?任何人都可以详细说明或指向我的一个很好的教程吗?
What other problems may there be with closures? Can anybody elaborate or point me to a good tutorial on this?
请注意,这个问题明确指向Node.js,而不是浏览器。 >
Please note that this question explicitly targets Node.js, and not the browser.
推荐答案
This question asks about something similar. Basically, the idea is that if you use a closure in a callback, you should "unsubscribe" the callback when you are finished so the GC know that it can't be called again. This makes sense to me; if you have a closure just waiting around to be called, the GC will have a hard time knowing that you're finished with it. By manually removing the closure from the callback mechanism, it becomes unreferenced and available for collection.
此外,Mozilla已发布一篇关于在Node.js 中查找内存泄漏的文章。我假设如果你尝试一些他们的策略,你可以找到你的代码表达泄漏行为的部分。最佳做法是好的和所有,但我认为更好地了解你的程序的需求,并提出一些个性化的最佳做法基于你可以凭经验观察。
Also, Mozilla has published a great article on finding memory leaks in Node.js code. I would assume that if you try out some of their strategies, you could find parts of your code that express leaky behavior. Best practices are nice and all, but I think it's more helpful to understand your program's needs and come up with some personalized best practices based on what you can empirically observe.
这里
- Jimb Esser的
node-mtrace
,它使用GCC
mtrace
实用程序来配置堆使用情况。
- Dave Pacheco的
节点-heap-dump
获取V8堆的快照,并在一个巨大的JSON文件中序列化整个事情。
- Danny Coates的
v8-profiler
和节点-inspector
为V8分析器提供了节点绑定,并使用WebKit Web检查器提供了一个节点调试接口。
- Felix Gnass的fork与取消禁用保留
- FelixGeisendörfer的节点内存泄漏教程是关于如何使用
v8-profiler
和node-debugger
,目前是大多数Node.js内存泄漏调试的最先进技术。
- Joyent的SmartOS平台一个用于调试Node.js内存泄漏的工具库
- Jimb Esser’s
node-mtrace
, which uses the GCCmtrace
utility to profile heap usage.- Dave Pacheco’s
node-heap-dump
takes a snapshot of the V8 heap and serializes the whole thing out in a huge JSON file. It includes tools to traverse and investigate the resulting snapshot in JavaScript.- Danny Coates’s
v8-profiler
andnode-inspector
provide Node bindings for the V8 profiler and a Node debugging interface using the WebKit Web Inspector.- Felix Gnass’s fork of the same that un-disables the retainers graph
- Felix Geisendörfer’s Node Memory Leak Tutorial is a short and sweet explanation of how to use the
v8-profiler
andnode-debugger
, and is presently the state-of-the-art for most Node.js memory leak debugging.- Joyent’s SmartOS platform, which furnishes an arsenal of tools at your disposal for debugging Node.js memory leaks
此问题的答案基本上说,您可以通过将 null
到闭包变量。
The answers to this question basically say that you can help the GC out by assigning null
to closure variables.
var closureVar = {};
doWork(function callback() {
var data = closureVar.usefulData;
// Do a bunch of work
closureVar = null;
});
函数返回时,任何声明为 除了在其他闭包中使用的。在这个例子中, closureVar
必须在内存中,直到调用 callback()
,但谁知道什么时候会发生?回调被调用后,您可以通过将闭包变量设置为null来向GC提示。
Any variables declared inside a function will go away when the function returns, except those that are used in other closures. In this example, closureVar
has to be in memory until callback()
is called, but who knows when that will happen? Once the callback has been called, you can give a hint to the GC by setting your closure variable to null.
DISCLAIMER :您可以从下面的评论看,有一些SO用户谁说这个信息是过时的和无关紧要的Node.js.我还没有一个确定的答案;我只是发布了我在网络上找到的。
DISCLAIMER: As you can see from the comments below, there are some SO users who say that this information is out of date and inconsequential for Node.js. I don't have a definitive answer on that yet; I'm just posting what I've found on the web.
这篇关于JavaScript中的内存泄漏和关闭 - 什么时候和为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!