HTML5 getImageData 的 JavaScript 内存泄漏

2023-11-25

我一直在努力为我正在创建的 JavaScript 游戏制作一些视觉效果,我注意到我用来调制精灵颜色的一段代码使我的浏览器内存使用量不断增加,看似没有限制。

您可以在此处查看代码和内存泄漏: http://timzook.tk/javascript/test.html

这种内存泄漏仅发生在我的 updateimage() 函数中,当我每帧从画布上下文中调用 getImageData (通过 setInterval)以便创建一个新的 ImageData 对象进行重新着色时。我本以为 javascript 的垃圾收集器会销毁旧的垃圾收集器,但如果不是的话,我不知道如何手动销毁它。任何帮助弄清楚为什么会这样做或如何解决它的帮助将不胜感激。

我的问题与这个非常相似:使用 getImageData、javascript、HTML5 canvas 会导致内存泄漏吗但是,我需要我的代码运行 setInterval 调用的函数中的每一帧,他将其移到 setInterval 函数之外的解决方案对我来说不是一个选择,而且我不能留下评论询问他是否找到了其他方法解决它。

测试人员请注意:由于此示例使用 getImageData,因此无法仅通过将其放入 .html 文件进行本地测试,因此需要 Web 服务器。而且它显然使用了 HTML5 元素,因此某些浏览器无法使用它。

编辑:*已解决*谢谢,下面的解决方案修复了它。我没有意识到您可以像在 drawImage() 中使用图像一样使用画布元素,我重组了我的代码,因此它现在使用的内存显着减少。如果有人想查看,我已将更改后的代码上传到上面链接的页面。


您的调用不会导致内存泄漏getImageData()。你的问题的根源是这一行:

TempImg.src = ImgCanvas.toDataURL("image/png");

实际上,每次执行该行代码时,浏览器都会“下载”另一个图像并将其存储在内存中。因此,您最终得到的实际上是一个增长非常快的缓存。您可以通过在 Chrome 中打开站点并检查开发人员工具的资源选项卡来轻松验证这一点(ctrl+shift+i).

您可以通过创建一个来解决这个问题TempImgCanvas并将图像数据存储在该画布上,而不是在每次调用后更新图像对象updateimage() loop.

我必须离开一段时间,但如果您愿意,我可以在回来后几个小时内编写一个示例。


Edit:我对事情进行了一些重组并消除了您的缓存问题。您只需要做两处更改。第一个是替换你的updateimage()与此功能:

function updateimage() {    
    var TempImgData = ImgContext.getImageData(0, 0, ImgCanvas.width, ImgCanvas.height);
    var NewData = TempImgData.data;
    var OrigData = ImgData.data;

    //Change image color
    var len = 4*ImgData.width*ImgData.height-1;
    for(var i=0;i<=len;i+=4) {
        NewData[i+0] = OrigData[i+0] * color.r;
        NewData[i+1] = OrigData[i+1] * color.g;
        NewData[i+2] = OrigData[i+2] * color.b;
        NewData[i+3] = OrigData[i+3];
    }

    //Put changed image onto the canvas
    ImgContext.putImageData(TempImgData, 0, 0);
}

第二个是更新最后一行draw()阅读如下:

drawImg(ImgCanvas, Positions[i].x, Positions[i].y, Positions[i].x+Positions[i].y);

使用此更新的代码,我们只需引用原始基础(白色)图像数据,并在每次遍历时根据该数据计算新值updateimage()功能。你打电话时getImageData()你收到一个copy画布上的图像数据,因此如果您编辑画布或数据,另一个保持不变。您一开始就已经获取了原始基础图像数据,因此只需使用它就有意义,而不必在每次更新时重新获取它。

另外,您会注意到我修改了循环,稍微改变了图像颜色。通过获取要访问/修改的实际数据数组的句柄,您就不必在每次循环时从父对象解析数组位置。这项技术实际上带来了相当不错的性能提升。你的表现一开始就很好,但提高效率也没什么坏处,因为它非常简单。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTML5 getImageData 的 JavaScript 内存泄漏 的相关文章

随机推荐