代码之家  ›  专栏  ›  技术社区  ›  Jonas Elfström

画布的javascript内存问题

  •  2
  • Jonas Elfström  · 技术社区  · 15 年前

    我在用 getImageData / putImageData 在HTML5画布上可以操作图片。 我的问题是浏览器似乎从来没有 free any memory . 直到我关闭标签(在Chrome和Opera中测试)。

    将其移出功能:

     var ctx = document.getElementById('leif').getContext('2d');
     var imgd = ctx.getImageData(0,0,width,height);
     var pix = imgd.data;
     var rndpixel = 0;
    

    问题就消失了!

    function infiniteLeif()
    {
      for (var i = 0; i<65536; i+=4) {
        rndpixel=Math.floor(Math.random()*(width*(height-2))+width+4) * 4;
        pix[rndpixel-wx4] = pix[rndpixel]; pix[rndpixel-wx4+1] = pix[rndpixel+1]; pix[rndpixel-wx4+2] = pix[rndpixel+2];
        pix[rndpixel+wx4] = pix[rndpixel]; pix[rndpixel+wx4+1] = pix[rndpixel+1]; pix[rndpixel+wx4+2] = pix[rndpixel+2];
        pix[rndpixel-4] = pix[rndpixel]; pix[rndpixel-4+1] = pix[rndpixel+1]; pix[rndpixel-4+2] = pix[rndpixel+2];
        pix[rndpixel+4] = pix[rndpixel]; pix[rndpixel+4+1] = pix[rndpixel+1]; pix[rndpixel+4+2] = pix[rndpixel+2];
      }
    
      ctx.putImageData(imgd,0,0);
      if (go==1) t=setTimeout(infiniteLeif,40);
    }
    

    example can be found here (建议使用Google Chrome)。

    这不是 setTimeout 这就是问题所在,因为我尝试了一个具有相同效果的循环。

    我逐渐明白删除循环引用通常是关键,但我真的有循环引用吗?如何更改此代码以便 JavaScript GC 有机会做这项工作吗?

    1 回复  |  直到 12 年前
        1
  •  2
  •   James Black    15 年前

    这可能对您的泄漏没有帮助,但您每40毫秒就要重新加载一个数组,其中的数据没有改变。

    您可能希望在初始化前后使用一个闭包。

    基本上,只需创建一个具有循环函数的变量,其中包含pix信息。

    然后,在不重新初始化的地方继续递归调用,但只在循环中使用变量。

    通过这种方式,您可以重用相同的pix信息,它保持它的状态,这应该很好,除非您在其他地方编辑画布。