如何在JavaScript中创建内存泄漏? [英] How do I create a memory leak in JavaScript?

查看:157
本文介绍了如何在JavaScript中创建内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解哪种代码会导致JavaScript中的内存泄漏并在下面创建脚本。但是,当我在OS X上的OS 6.0.4中运行脚本时,活动监视器中显示的内存消耗并没有真正增加。

I would like to understand what kind of code causes memory leaks in JavaScript and created the script below. However, when I run the script in Safari 6.0.4 on OS X the memory consumption shown in the Activity Monitor does not really increase.

我的脚本或者脚本有问题现在的浏览器不再是这个问题吗?

Is something wrong with my script or is this no longer an issue with modern browsers?

<html>
<body>
</body>
<script>
var i, el;

function attachAlert(element) {
    element.onclick = function() { alert(element.innerHTML); };
}

for (i = 0; i < 1000000; i++) {
    el = document.createElement('div');
    el.innerHTML = i;
    attachAlert(el);
}
</script>
</html>

该脚本基于Google JavaScript风格指南的Closure部分:
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone =闭包#闭包

The script is based on the Closure section of Google's JavaScript style guide: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Closures#Closures

编辑:导致上述代码泄漏的错误显然已经修复: http://jibbering.com/faq/notes/closures/#clMem

The bug that caused the above code to leak has apparently been fixed: http://jibbering.com/faq/notes/closures/#clMem

但是我的问题遗骸:有人能够提供一个现实浏览器泄漏内存的JavaScript代码的真实示例吗?

But my question remains: Would someone be able to provide a realistic example of JavaScript code that leaks memory in modern browsers?

互联网上有很多文章表明内存泄漏可能是复杂的单页面应用程序的问题,但我很难找到可以在浏览器中运行的示例。

There are many articles on the Internet that suggest memory leaks can be an issue for complex single page applications but I have a hard time finding an examples that I can run in my browser.

推荐答案

你'不要保留你创造的元素并在任何地方引用 - 这就是为什么你没有看到内存使用量的增加。尝试将元素附加到DOM,或将其存储在对象中,或将onclick设置为一个不同的元素。然后你会看到内存使用率飙升。垃圾收集器将通过并清理任何无法再引用的内容。

You're not keeping the element you've created around and referenced anywhere - that's why you're not seeing the memory usage increase. Try attaching the element to the DOM, or store it in an object, or set the onclick to be a different element that sticks around. Then you'll see the memory usage skyrocket. The garbage collector will come through and clean up anything that can no longer be referenced.

基本上是代码的演练:


  • 创建元素(el)

  • 创建一个引用
    元素的新函数

  • 将该函数设置为该元素的onclick

  • 用新元素覆盖元素

  • create element (el)
  • create a new function that references that element
  • set the function to be the onclick of that element
  • overwrite the element with a new element

一切都围绕着存在的元素。一旦无法访问该元素,就无法再访问该onclick。因此,由于无法访问onclick,所以创建的函数被销毁了。函数只有对元素的引用..所以元素也被清理了。

Everything is centric around the element existing. Once there isn't a way to access the element, the onclick can't be accessed anymore. So, since the onclick can't be accessed, the function that was created is destroyed.. and the function had the only reference to the element.. so the element is cleaned up as well.

有人可能有一个更技术性的例子,但这是我对javascript垃圾收集器理解的基础。

Someone might have a more technical example, but that's the basis of my understanding of the javascript garbage collector.

编辑:这是以下几种可能性之一您的脚本的泄漏版本:

Here's one of many possibilities for a leaking version of your script:

<html>
<body>
</body>
<script>
var i, el;

var createdElements = {};
var events = [];

function attachAlert(element) {
    element.onclick = function() { alert(element.innerHTML); };
}

function reallyBadAttachAlert(element) {
    return function() { alert(element.innerHTML); };
}

for (i = 0; i < 1000000; i++) {
    el = document.createElement('div');
    el.innerHTML = i;

    /** posibility one: you're storing the element somewhere **/
    attachAlert(el);
    createdElements['div' + i] = el; 

    /** posibility two: you're storing the callbacks somewhere **/
    event = reallyBadAttachAlert(el);
    events.push(event);
    el.onclick = event;

}
</script>
</html>

因此,对于#1,你只是在某个地方存储对该元素的引用。无论您永远不会使用它 - 因为该引用是在对象中进行的,元素及其回调将永远不会消失(或者至少在您从对象中删除元素之前)。对于可能性#2,您可以将事件存储在某处。因为可以访问该事件(即通过执行事件[10](); ),即使该元素无处可寻,它仍然被事件引用..所以元素将保留在内存和事件中,直到它从数组中删除。

So, for #1, you're simply storing a reference to that element somewhere. Doesn't matter that you'll never use it - because that reference is made in the object, the element and its callbacks will never go away (or at least until you delete the element from the object). For possibility #2, you could be storing the events somewhere. Because the event can be accessed (i.e. by doing events[10]();) even though the element is nowhere to be found, it's still referenced by the event.. so the element will stay in memory as well as the event, until it's removed from the array.

这篇关于如何在JavaScript中创建内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆