Canvas消耗大量内存

时间:2011-10-05 08:22:52

标签: html5 google-chrome memory-leaks canvas html5-canvas

我在使用叠加层打开的Canvas实现方面遇到了困难。 画布元素宽760px,高2640px(我知道,不要问)。

我每27.5px高处画线。

ctx.moveTo(0, y);
ctx.lineTo(760, y);
ctx.strokeStyle = 'rgb(100,100,100)';
ctx.stroke();

在创建画布时,浏览器似乎对此“窒息”了。最终它通过(1-5secs)并且内存提高了20MB。

关闭叠加层似乎没有释放此内存。 当我重新打开叠加层(重绘画布)时,内存再次增加。 等等等等... 我的镀铬工艺很快就会从60MB内存变为600+。

将画布调整为264px高,每2.75px绘制线条的速度更快,仅消耗约4MB(当然也不会被清除)。

谁对如何避免这种情况有一些指示。

<小时/> 这是更多的代码 data是一个包含Entries属性的对象数组,该属性也是一个数组。

[ { Entries : [{...},{...},...] }, {...}, ... ]

var $canvas = container.find('canvas')
    , canvas = $canvas.get(0)
    , maxY = canvas.height
    , maxX = canvas.width
    , dX = maxX / (data.length + 1)
    , ctx = canvas.getContext('2d');


var x1, y1, y2, mh;

$.each(data, function (i, day) {
    if (!day.Entries) return;

     $.each(day.Entries, function (j, entry) {
         x1 = (i + 1) * dX;
         mh = entry.BeginDate.toHourMinutes();
         y1 = (((mh.h * 60) + mh.m) / 1440) * maxY;
         mh = entry.EndDate.toHourMinutes();
         y2 = (((mh.h * 60) + mh.m) / 1440) * maxY;

         switch (entry.Type) {
             case CALENDARTYPES.OPENINGHOUR:
                 ctx.beginPath();
                 ctx.rect(x1, y1, dX - 10, y2 - y1);
                 ctx.fillStyle = "rgb(125, 125, 125)";
                 ctx.fill();
                 ctx.closePath();
                 break;
             case CALENDARTYPES.BLOCKING:
                 ctx.clearRect(x1, y1, dX, y2 - y1);
                 break;
         };
      });
  });

       delete x1, y1, y2, mh;

       //Draw grid on canvas.

       var x = 0
           , y = +0.5
           , stepYH = maxY / 24
           , stepYQ = stepYH / 4
           , isHour = true;

       ctx.lineWidth = 1;

       while (y < maxY) {
           isHour = (((y - 0.5) % stepYH) == 0);
           ctx.moveTo(isHour ? x : x + dX, y);
           ctx.lineTo(maxX, y);
           ctx.strokeStyle = isHour ? 'rgb(175,175,175)' : 'rgb(100,100,100)';
           ctx.stroke();
           y += stepYQ;
       };

2 个答案:

答案 0 :(得分:4)

根据评论:

如果你没有清除路径,你基本上是在扩展路径,并且由于.stroke()描绘了(整个)路径,当你使用{{{{}}添加更多点时,你最终会越来越多地绘制1}} / .moveTo

使用.lineTo可能更有意义,因此您只需要描绘新路径而不是旧路径:

  • 从内存中清除路径 - 减少泄漏
  • 不再画出旧路径 - 减少性能损失

答案 1 :(得分:2)

编辑:看起来@pimvdb用他的解决方案击中了头部。省略开始和结束路径调用确实会继续构建一条永无止境的路径。


您是否可以发布足够的代码以便我们查看此问题?

除非Chrome中有一些我不知道的非常模糊的错误,否则使用具有指定尺寸的画布不是问题。我已经研究过如此规模的全屏画布应用程序并且没有任何问题。

增加20MB的内存似乎有点过分,所以我倾向于认为你在内存中不必要地创建了canvas元素(或与之相关的东西)的副本。您可以通过关闭和打开显示并重新绘制画布的叠加层来按需增加内存消耗这一事实强化了这一信念。

如果您可以发布您的代码,我很乐意看一下它并帮助您确定问题。