JavaScript(Chrome)中的内存泄漏问题

8
我每秒钟调用一个函数50次,该函数会在<canvas>元素上绘制一些昂贵的东西。虽然没有问题,但我查看了内存使用情况,发现它每秒钟占用1MB的RAM。Chrome似乎进行垃圾回收,因为它每隔一分钟左右就会下降,但然后使用量又增加了。
我尝试在函数中的某些位置放置return,以便确定我的函数的哪个部分导致泄漏。我已经成功将其缩减到特定的代码行,之后就出现了问题,但我不知道如何解决它。
我的问题是:
  • 有什么工具可以有效地测量Chrome中的JavaScript内存泄漏吗?
  • 在使用变量后将其设置为null/undefined是否有效,类似于处理它们?
如果源代码真的必要,我会毫不犹豫地在这里发布它,但我必须承认它既长又可能难以理解。
2个回答

9

我直接引用文章中的一句话:

说到内存泄漏,打破循环引用(导致泄漏的原因)通常使用简单的null赋值来完成。通常不需要使用delete。此外,null赋值允许“取消引用”变量,这是delete通常无法实现的。

var el = document.getElementById('foo');
// circular reference is formed
el.onclick = function() { /* ... */ };
// circular reference is broken
el = null;
// can't `delete el` in this case, as `el` has DontDelete

出于这些原因,打破循环引用时最好使用null赋值。查看 delete 解释

实际上,我没有循环引用。在我的渲染器函数中,所有自定义的“Vector”类都代表3D和2D中的点。如果我每秒调用该函数50次,我猜它们会在内存中累积。将其设置为null是否仍然有帮助?目前我一直在尝试实验,但都无济于事,无论是使用“delete”还是“= null”。 - pimvdb
@pimvdb 读一下这篇文章,虽然很长但非常详细地展示了删除操作的实际工作原理。我无法确定哪个选项对你会更成功。JS泄漏总是让人头疼。 - Andrew

3
在Chrome开发者工具的“Profiles”选项卡下查看堆配置文件,以获取有关内存使用情况的信息。
以下是防止内存泄漏的方法:
- 使用JSLint测试您的代码,以查看是否会给您提供一些指针。 - 使用var关键字为变量提供函数作用域,这样它们在超出范围时可以进行垃圾回收。如果没有var关键字,变量将具有全局作用域。 - 使用delete variable;语句从内存中删除对象及其引用。将变量设置为null只会从内存中删除对象,而不会删除其引用。

谢谢。你知道for循环的变量(例如i)在for循环结束后是否会自动释放吗? - pimvdb
4
它不会,因为在JavaScript中只有函数定义作用域。在这里阅读有关JavaScript作用域的更多信息:http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting - Martin Jespersen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接