簡體   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