【问题标题】:Canvas native methods eating lot of RAM画布本机方法会占用大量 RAM
【发布时间】:2016-04-08 05:20:03
【问题描述】:

我正在编写一个可以基于单个像素在 HTML5 Canvas 上执行操作的软件。基本上,我获取所有像素,更新 RGB 的值并使用本机方法 getImageData、createImageData 和 putImageData 将它们写回。

在进行一些测试时,我发现我的软件使用了大量 RAM,远远超过 javascript 使用的数量。所以我创建了this github repo 来逐个删除可能导致内存消耗的每个元素,我发现它是由这些本机方法引起的。我知道这个软件可以改进很多,但这并不能解释这个效果。以它为例。

您可以通过更改为不同的提交来查看 RAM 消耗的影响:第一个是最差的,倒数第二个是最好的。通过浏览不同的提交,您可以看到使用的内存似乎“可解释”的唯一版本是 this commit,我已经删除了对画布原生方法的所有引用。

有趣的是,使用的内存没有被内存分析器捕获:就像 chrome 使用的一些内存不依赖于我的 javascript。尝试运行 this commit 并使用本地任务管理器(例如 htop)和 google 调试工具 js heap voice 查看内存量。差别很大。

所有这些测试都是在 Chrome 47 上完成的;火狐好像没有这个问题。

这是正常的还是我做错了什么?为什么每次调用这些方法都不会释放内存,而是继续累积,产生内存泄漏?

【问题讨论】:

  • 想知道这是用什么引擎测试的,V8 (Chrome)、SpiderMonkey (Firefox)、Chakra (IE)?
  • 你是对的。我已经在 chrome 47 上测试了我的软件。似乎 Firefox 没有这个问题,但我更愿意对此进行更多调查。
  • 可能(可能?)使用内存: 虽然我没有查看您的链接代码,但.getImagData 是内存不足的,因为它使用每个“get”,因为它的任何工作都没有委托给 GPU。 GC 可能需要一段时间才能回收——是的,不同浏览器上的 GC 行为会有所不同。

标签: javascript html canvas memory-leaks html5-canvas


【解决方案1】:

对此的首选答案是拿出一个分析器并检查

现在查看您的代码,我看到了:

pixels.forEach(function(pixel) {
  var interval = 1, x, y, square=[];
  for (x=-interval; x<interval; x++)
    for (y=-interval; y<interval; y++) {
      var tmp = getPixel(pixel.x + x, pixel.y + y);
      if (tmp) square.push(tmp);
    }
});

为每个像素创建一个数组square。你的记忆猪就在那里。随着像素数量的增长,您将创建相同数量的数组。我不确定在哪里使用square。它只是接受价值观。

此外,您还有一个 3 级循环。我们都知道forEach 比您的常规循环慢。你可能想改变你的逻辑来避免这种情况。

至于 GC 何时启动,这取决于浏览器。您无法真正判断它何时启动,但您当然可以通过密切关注您如何创建对象等内容来避免它。

【讨论】:

  • 嗨 Joseph,我正在使用 chrome 调试工具分析我的代码,使用 CPU 分析并使用堆分配内存获取时间线。这种方法的问题在于 js 堆分析器没有解释使用本机方法产生的内存消耗。我认为chrome使用的内存不依赖于我的javascript,我的代码试图证明这一点。我不同意你的analisys:在this commit我删除了for和square部分,但使用的内存仍然无法解释。
  • @Duma 最好将你的代码和发现也放在你的帖子中:)
猜你喜欢
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多