Javascript内存泄漏setTimeout问题

3

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

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' 方法在其定义内部调用自身,因此闭包变量将在内部 check 方法执行时可用,然后再为 test 函数创建一个执行上下文等等。

此外,在每个执行中,我们都会创建一个 Uint16Array 的内存块,我相信它是在堆中分配的,并且由于从闭包中可以访问到,所以永远不会被释放。

内存概况:enter image description here

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


你的标题为什么声称存在内存泄漏问题,而事实上你展示的是不存在内存泄漏? - cookie monster
1
uArr只是一个本地变量,它的生命周期仅限于check()函数的当前执行。一旦check()的调用完成,该调用的局部变量就有资格进行垃圾回收,因为不再有可以访问它们的代码。在闭包中无限期存活的唯一变量是node - jfriend00
1个回答

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

这个关于闭包的页面可能会有所帮助。

虽然如果有N次对check()的调用,就会创建N个闭包(以及N个node的副本),但setTimeout()在调用check()后会释放其对check()的引用。因此,也不会有泄漏问题。


你的第一句话并不完全正确。如果你在一个for循环中调用一个带有匿名完成回调函数作为参数的异步函数,并且该循环执行了N次迭代,那么你将得到N个独立的闭包。布局确定了会有一个闭包,但是由于执行路径的原因,这N个闭包本身是在代码执行时创建的。 - jfriend00
@jfriend00 您是正确的。谢谢!我已经修改了我的答案。 - cybersam

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