javascript
2012-05-09 119 views 0 likes 
0
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; 
} 

一旦上面的函数正在运行,页面就不能交互,页面的内存和CPU使用率就会飞涨。为什么这个函数导致内存泄漏

这是传递给该功能的参数b的例子:

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

b.length个不大于2,并执行该功能不超过三次。如果此功能被删除,内存泄漏将不会发生。

UPDATE:

继@GarethMcCaughan的建议下,我加入警报(我)到循环的顶部,它不断提醒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>'; 
    } 
    ...... 
} 

为你在评论中看到,如果我用console.log替换调用,日志只显示4次执行。但为什么函数被重复调用?

然后我发现控制台在循环的顶部报告了一个断点(我已经注释掉了),这是函数继续调用的原因吗?

+0

确定吗?这里一切都很好。你使用的是什么浏览器? –

+1

你可能想在代码中加入一些'alert'来验证(1)'parseAttach'没有被调用很多次,(2)'b.length'确实不是很长,以及(3)它的功能确实在于你的脚本花费所有时间。 –

+1

(我强烈怀疑至少1,2,3中的一个实际上并不是这种情况。) –

回答

0

在两个循环中,您都没有在i变量之前放置var。这意味着它是全球性的。如果它是全球性的,那么两个循环都使用相同的i

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

加var和它应该修复它:

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

编辑:进一步澄清:

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]); 
    } 
    ...... 
} 

因此,外循环的退出条件,从来没有遇到过,每循环迭代i回到i永远不会到达​​。

+0

在一百万年内不会造成如此大的泄漏。 – DanRedux

+0

@DanRedux没有泄漏。它造成了无限循环。每次调用该函数都会将“i”设置回0. –

+0

是的,但是除非他从循环内部调用函数,否则不会导致循环,而不是循环内的函数。我在循环中不受影响。我看到他接受了这个答案,所以现在我知道这个“随机猜测”起作用了,但我想知道我受到了什么影响。 – DanRedux

0

除了一个bug之外,一切似乎都很好:你忘了让计数器变量i为本地。当从一个循环调用时,该代码将重置外环的同名计数器变量(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 

的无限循环会使你的浏览器挂起,冻结界面直到代码执行。某些浏览器可能会针对运行时间过长的脚本发出错误,并执行超时。

相关问题