【问题标题】:Javascript memory leak setTimeout issueJavascript内存泄漏setTimeout问题
【发布时间】:2014-06-07 14:52:54
【问题描述】:

有人知道为什么这里的内存消耗保持不变吗?

var count = 0;
$(init);

function init(){
    var node =  document.querySelector('.logs');

    function check(){
        var uArr = new Uint16Array(100);
        log(node, uArr.length);
        setTimeout(check,100);
    }   
    setTimeout(check,100);
}      


function log(node, text){
    if( count % 30  == 0 ){
        node.innerHTML = '';
    }
    var child = document.createElement('div');
    child.innerText = 'count ' + (count++) + " arr len "  + text;
    node.appendChild(child);
}

http://jsfiddle.net/V99Eb/11/

它应该线性增加内存分配的原因是:'check' 方法在其定义中调用自身,因此闭包变量将可用于内部检查方法执行,然后再次为测试函数创建一个执行上下文,并且很快。

此外,在每次执行中,我们都会创建一个 Uint16Array 的内存块,我认为它是在堆中分配的,并且永远不应该被解除分配,因为它可以从闭包中访问。

内存配置文件:

查看内存时间线,似乎并没有随着时间的增加而增加内存分配。这是预期的行为吗?

【问题讨论】:

  • 为什么您的标题声称存在内存泄漏问题,而实际上您证明没有内存泄漏?
  • uArr 只是一个局部变量,它的生命周期只是check() 的当前执行。一旦对check() 的一次调用完成,该调用的局部变量就有资格进行垃圾回收,因为不再有任何代码可以访问它们。唯一在闭包中无限期存在的变量是node

标签: javascript performance memory-management memory-leaks javascript-debugger


【解决方案1】:

uArr 只是一个局部变量,在check() 退出后被分配、使用和垃圾回收。 check() 内部没有闭包。 setTimeout()check() 调用(但未定义)。

This page on Closures 可能会有所帮助。

虽然确实如果有 N 次对 check() 的调用,则会创建 N 个闭包(以及 node 的 N 个副本),setTimeout() 将在它之后释放对 check() 的引用调用它。因此,那里也没有泄漏。

【讨论】:

  • 你的第一句话不太对。如果您在执行 N 次迭代的 for 循环中调用带有匿名完成回调函数作为参数的异步函数,您将获得 N 个单独的闭包。布局确定会有一个闭包,但 N 个闭包本身是作为执行的代码创建的,因为执行路径。
  • @jfriend00 你是对的。谢谢!我修改了答案。
猜你喜欢
  • 1970-01-01
  • 2012-12-19
  • 2013-04-10
  • 1970-01-01
  • 2021-01-25
  • 1970-01-01
  • 2016-07-28
相关资源
最近更新 更多