繁体   English   中英

使用HTML5 getImageData泄漏javascript内存

[英]javascript memory leak with HTML5 getImageData

我一直在努力为我正在创建的javascript游戏制作一些视觉效果,我注意到我用来调制我的精灵颜色的一段代码使我的浏览器内存使用率上升,似乎没有限制。

你可以在这里看到代码和内存泄漏: http //timzook.tk/javascript/test.html

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

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

测试它的人注意:由于此示例使用getImageData,因此只能通过将其放在.html文件中进行本地测试,需要Web服务器。 此外,它显然使用HTML5元素,因此一些浏览器将无法使用它。

编辑:*已解决*谢谢,下面的解决方案修复了它。 我没有意识到你可以像使用drawImage()中的图像一样使用canvas元素,我重构了我的代码,所以它现在使用的内存要少得多。 我将此更改的代码上传到上面链接的页面,如果有人想看到它。

您没有通过调用getImageData()获得内存泄漏。 您的问题的根源是这一行:

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

实际上,每次执行该行代码时,浏览器“下载”另一个图像并将其存储在存储器中。 所以,你实际上最终得到的是一个快速增长的缓存。 您可以通过在Chrome中打开网站并查看开发人员工具的资源标签( ctrl+shift+i )轻松验证这一点。

您可以通过创建TempImgCanvas并将图像数据存储在该画布上而不是在每次调用updateimage()循环后更新图像对象来updateimage()

我必须离开一段时间,但如果你愿意的话,我可以在几个小时内找到一个例子。


编辑:我稍微重组了一些东西并消除了你的缓存问题。 你只需要进行两处修改。 第一个是用这个替换你的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()您会在画布上收到图像数据的副本 ,因此如果您编辑画布或数据,则另一个保持不变。 您已经开始抓取原始基本图像数据,因此只使用它而不必在每次更新时重新获取它都是有意义的。

此外,您会注意到我修改了您的循环,稍微改变了图像颜色。 通过获取要访问/修改的实际数据数组的句柄,每次进行循环时都可以保存自己必须从父对象解析数组位置。 这种技术实际上可以带来非常好的性能提升。 你的表现很好,但是因为它非常简单,所以效率更高也不会有什么坏处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM