简体   繁体   English

为什么此功能导致内存泄漏

[英]Why this function causes memory leak

function parseAttach(b)
{
    var h="";
    for(i=0;i<b.length;i++)
    {
        var a=b[i];
        switch(a['type'])
        {
            case "image":
                h+='<li class="attach aImg" style="background:#000;border-bottom:2px solid #fff"><img style="max-width:425px;max-height:500px" src="http://img.xiami.com/u/phoo/'+a['file']+'"></li>';
            break;
            case "video":
                h+='<li class="attach aVideo" style="background:#f3f3f3"><span class="MxND" f="'+a['from']+'" d="'+a['id']+'"></span></li>';
            break;
            case "music":
                h+='<li class="attach aMusic"><embed src="http://www.xiami.com/widget/0_'+a['id']+'/singlePlayer.swf" type="application/x-shockwave-flash" width="257" height="33" wmode="transparent"></embed></li>';
            break;
        }
    }
    return h;
}

Once above function is running, the page cannot be interacted, memory and cpu usage of that page skyrocket. 一旦上述功能运行,该页面将无法交互,该页面的内存和CPU使用率急剧上升。

this is an example of parameter b passed to this function: 这是传递给此函数的参数b的示例:

[{"type":"video","from":"k6","id":"kyxGTZbD-vQ8Domm-eeHiQ"}]

b.length is not more than 2 and this function was executed no more than three times. b.length不大于2,并且此函数执行的次数不超过3次。 If this function is removed, memory leaking will not happen. 如果删除此功能,则不会发生内存泄漏。

UPDATE: 更新:

Following @GarethMcCaughan 's suggestion, I added alert(i) to the top of the loop, it keeps alerting 0, I headed to the invocation code: 遵循@GarethMcCaughan的建议,我在循环的顶部添加了alert(i),它保持警报0,我转到调用代码:

for(i=0;i<c[0].length;i++)//the breakpoint
{
    ......
    if(t[6].length>0)
    {
        //console.log(t[6].length);
        //var a=parseAttach(t[6]);
        var a="";
        h+='<ul class="attaches">'+a+'</ul>';
    }
   ......
}

as you see in the comment, if I replace the invocation with a console.log, the log only show 4 times of execution. 如您在注释中看到的,如果我用console.log替换调用,则日志仅显示4次执行。 But why the function are invoked repeatedly? 但是,为什么函数会被反复调用?

Then I found the console report a breakpoint at the top of the loop(I've comment it out), is this the reason why the function keeps invoking? 然后我发现控制台在循环的顶部报告一个断点(我已将其注释掉),这是该函数不断调用的原因吗?

In both of your loops you have not put var before your i variable. 在两个循环中,都没有将var放在i变量之前。 This means it is global. 这意味着它是全球性的。 If it is global then both loops are using the same i . 如果是全局的,则两个循环都使用相同的 i

for(i=0;i<b.length;i++)

add var and it should fix it: 添加var,它应该修复它:

for(var i=0;i<b.length;i++)

EDIT : Further clarification: 编辑 :进一步说明:

for(i=0;i<c[0].length;i++)
{
    ......
    if(t[6].length>0)
    {
        // THIS CALL WILL SET THE GLOBAL i TO t[6].length
        var a=parseAttach(t[6]);
    }
   ......
}

Therefore, the exit condition of the outer loop is never met, every iteration of the loop sets i back so that i never reaches c[0].length . 因此,永远不会满足外部循环的退出条件,循环的每次迭代都会将i设置回去,这样i永远不会达到c[0].length

Everything seems fine apart from one bug: You forgot to make the counter variable i local. 一切似乎都来自一个错误除了罚款:你忘了使计数器变量i地方。 When invoked from a loop, the code would reset the same-named counter variable of the outer loop (to 2, as this is the max length) and make it never reach its end condition: 从循环中调用时,代码会将外部循环的同名计数器变量重置为2(这是最大长度),并使其永远不会达到结束条件:

var i; // this variable will always be referenced
function x(number) {
    for (i=0; i<number; i++)
        dosomething;
}
for (i=0; i<5; i++)
    x(2); // resets i to 2
// => never-ending loop

The infinite loop will make your browser hang, freezing the interface until the code is executed. 无限循环将使您的浏览器挂起,冻结接口,直到执行代码为止。 Some browser might throw an error for too-long-running scripts, implemented with a timeout. 某些浏览器可能会为超时运行的脚本运行时间过长而引发错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM