javascript
2012-05-09 17 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に警告し続ける、ループの先頭にアラート(i)を追加、私は、呼び出しコードに向かっ:

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

'parseAttach'が膨大な回数呼び出されていないこと、(2)' b.length'が実際にはあまり長くないことを確認するために、あなたのコードに 'alert'をいくつか入れたいかもしれません、そして(3)本当にあなたのスクリプトがすべての時間を費やしているということです。 –

+1

(1,2,3のうちの少なくとも1つが実際にはそうでないことが強く疑わしい) –

答えて

0

両方のループで、i変数の前にvarを入れていません。これはそれがグローバルであることを意味します。グローバルであれば、両方のループはと同じiを使用しています。

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

VARを追加し、それはそれを修正する必要があります

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

はEDIT:さらに明確化:

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

1つのバグを除いて、すべてうまくいくように見えます。カウンタ変数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 

無限ループブラウザがハングアップし、コードが実行されるまでインターフェイスがフリーズします。タイムアウトで実装された長時間実行されるスクリプトでは、ブラウザによってはエラーが発生することがあります。

関連する問題