在Chrome等中使用canvas操作(fillRect()等)时内存消耗问题

时间:2017-06-23 10:44:07

标签: javascript html5 canvas gwt

我有一个用GWT编写的应用程序,看起来有点像甘特图。它工作得很好但有时候我对应用程序的内存使用有一些问题。为了绘制图表我使用一个大画布,例如宽度10000像素和高度2500像素。最初绘制我的图表时一切都很好(Chrome 50 MB内存使用率,Chrome 150 MB内存使用率(来自Chrome任务管理器))。 问题从重新绘制图表的某些部分开始,例如可以选择某些内容,这意味着单击的rect应该获得另一种颜色。在那种情况下,我重新绘制与我的rect相交的所有新东西,例如整个尺寸为40 x 10 px的其他5个rects。这实际上是内存消耗,JavaScript内存使用几乎是固定的,但内存使用量增加了大约100 MB。为什么?如果我的画布较小,例如1500 x 1000像素,并且我执行相同的操作,则内​​存使用量也会增加但仅为50 MB。 这就是为什么我认为这个问题与我在JavaScript / GWT中的编码无关,它有一些关于chromes如何在画布上处理绘画的事情。是否有可能看到,什么消耗所有的记忆?使用Chrome开发工具,我只能看到所有的JavaScript内容。但JavaScript的内存使用几乎是固定的。我读了一些关于chrome内部跟踪工具的内容。但是如果你不了解铬的内部结构,这真的很难理解。还有什么可能是内存使用的原因? 如果是在画布上重新粉刷,我该怎么办?我读了一些关于画布/渲染策略的内容:

  1. 后台渲染(创建第二个更改大小的画布,在此画布上绘制所有更改并将其放置在原始的大画布中)
  2. 多画布(创建第二个更改大小的画布,在此画布上绘制所有更改,并将此画布放在orignal顶部的正确位置,大页面作为html页面中的第二个画布),
  3. 一个适合屏幕大小的画布,你只绘制一个小孔视图,当你“滚动”时,你必须重新绘制缺失的部分(我认为chrome trace工具就像这样工作,不管它?)
  4. 首先在我的应用程序中很容易实现它,2。有点复杂而且3.非常困难。其中一个策略会解决我的问题吗?如果是策略c),实施它的最佳方法是什么? GWT框架或HTML5 / canvas本身是否有任何支持?什么是滚动面板的用法,因为画布具有固定的大小?跟踪工具如何做到这一点?

    非常感谢,Szdnez

2 个答案:

答案 0 :(得分:0)

图像大小10000乘2500仅使用10000 * 2500 * 4字节(100mb)存在。根据您使用该图像的方式以及GPU及其RAM的功能,将会有更多使用。

如果没有代码,就无法确定内存使用的位置以及浪费和不必要的地方。

Chromes任务管理器显示使用的总内存,这包括代码不再引用的内存,只是等待GC(垃圾收集,内存管理系统的一部分)进行清理。如果需要,浏览器将强制GC清理。内存使用情况(如任务管理器中所示)可以远远超过100MB,而实际上你只使用100mb。

答案 1 :(得分:0)

总使用量为100-150 MB不是问题。问题是,我在我的代码中有一些操作,另外使用大约100 MB。 在经过大量的尝试和错误以及逐行取消/评论之后,我发现了瓶颈(我希望我找到它)。例如,在我重绘矩形之前,我做了一些修剪,以便只重绘一个特殊区域(简化代码示例):

context2d.save()

context2d.rect( x, y, width, height );
context2d.clip();

redrawRectangle();

context2d.restore;

使用此代码,内存使用量增加200 MB。如果我跳过剪辑:

// context2d.rect( x, y, width, height );
// context2d.clip();

内存使用率几乎稳定。在这种情况下,我真的不需要裁剪。但为什么它这么“昂贵”?还有其他可能吗?

谢谢,Szdnez