Safari中的数据URI泄漏(是:使用HTML5画布的内存泄漏) [英] Data URI leak in Safari (was: Memory Leak with HTML5 canvas)

查看:552
本文介绍了Safari中的数据URI泄漏(是:使用HTML5画布的内存泄漏)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个网页,通过Websocket接收base64编码位图,然后将它们绘制到画布上。它工作完美。除非,浏览器(无论是Firefox,Chrome还是Safari)的内存使用量随着每个图片而增加,并且永远不会下降。所以,在我的代码或一些其他错误必须有内存泄漏。如果我注释掉对context.drawImage的调用,内存泄漏不会发生(但当然图像从来不会绘制)。以下是我的网页的片段。任何帮助是赞赏。谢谢!

I have created a webpage that receives base64 encoded bitmaps over a Websocket and then draws them to a canvas. It works perfectly. Except, the browser's (whether Firefox, Chrome, or Safari) memory usage increases with each image and never goes down. So, there must be a memory leak in my code or some other bug. If I comment out the call to context.drawImage, the memory leak does not occur (but then of course the image is never drawn). Below are snippets from my webpage. Any help is appreciated. Thanks!

// global variables
var canvas;
var context;

...

ws.onmessage = function(evt)
{
    var received_msg = evt.data;
    var display_image = new Image();
    display_image.onload = function ()
    {
        context.drawImage(this, 0, 0);
    }
    display_image.src = 'data:image/bmp;base64,'+received_msg;
}

...

canvas=document.getElementById('ImageCanvas');
context=canvas.getContext('2d');

...

<canvas id="ImageCanvas" width="430" height="330"></canvas>






UPDATE 12/19/2011


UPDATE 12/19/2011

我可以通过使用createElement / appendChild和removeChild动态创建/销毁画布来解决这个问题。之后,我在Firefox和Chrome上没有更多的内存问题。

I can work around this problem by dynamically creating/destroying the canvas every 100 images or so with createElement/appendChild and removeChild. After that, I have no more memory problems with Firefox and Chrome.

但是,Safari仍然有内存使用问题,但我认为这是一个不同的问题,帆布。在Safari中重复更改图片的src似乎有一个问题,因为它永远不会释放此内存。

However, Safari still has a memory usage problem, but I think it is a different problem, unrelated to Canvas. There seems to be an issue with repeatedly changing the "src" of the image in Safari, as if it will never free this memory.

display_image.src = 'data:image/bmp;base64,'+received_msg;  

这是在以下网站上描述的相同问题: http://waldheinz.de/2010/06/webkit-leaks-data-uris/

This is the same problem described on the following site: http://waldheinz.de/2010/06/webkit-leaks-data-uris/

UPDATE 12/21/2011

UPDATE 12/21/2011

我希望通过转换我的接收base64字符串到一个blob(与我在这个网站上找到的dataURItoBlob函数),并回到一个URL与window.URL.createObjectURL,设置我的图像src到这个URL,然后通过调用窗口释放内存。 URL.revokeObjectURL。我得到这一切工作,Chrome和Firefox正确显示图像。不幸的是,Safari看起来不支持BlobBuilder,所以它不是一个我可以使用的解决方案。这是奇怪的,因为许多地方,包括O'Reilly编程HTML5应用程序书状态,BlobBuilder在Safari / WebKit夜间构建中支持。我从 http://nightly.webkit.org/ 下载了最新的Windows夜间版本,并运行了WebKit.exe,但BlobBuilder和WebKitBlobBuilder仍然未定义。

I was hoping to get around this Safari problem by converting my received base64 string to a blob (with a "dataURItoBlob" function that I found on this site) and back to a URL with window.URL.createObjectURL, setting my image src to this URL, and then later freeing the memory by calling window.URL.revokeObjectURL. I got this all working, and Chrome and Firefox display the images correctly. Unfortunately, Safari does not appear to have support for BlobBuilder, so it is not a solution I can use. This is strange, since many places including the O'Reilly "Programming HTML5 Applications" book state that BlobBuilder is supported in Safari/WebKit Nightly Builds. I downloaded the latest Windows nightly build from http://nightly.webkit.org/ and ran WebKit.exe but BlobBuilder and WebKitBlobBuilder are still undefined.

UPDATE 01/03/2012

UPDATE 01/03/2012

,我终于通过用atob()解码base64编码的数据URI字符串,然后创建一个像素数据数组,并用putImageData将它写到画布上来解决这个问题(参见 http://beej.us/blog/2010/02/html5s-canvas-part-ii-pixel-manipulation/ )。这样做(相对于不断修改图像的src和调用drawImage在onload函数),我不再看到在Safari或任何浏览器的内存泄漏。

Ok, I finally fixed this by decoding the base64-encoded data URI string with atob() and then creating a pixel data array and writing it to the canvas with putImageData (see http://beej.us/blog/2010/02/html5s-canvas-part-ii-pixel-manipulation/). Doing it this way (as opposed to constantly modifying an image's "src" and calling drawImage in the onload function), I no longer see a memory leak in Safari or any browser.

推荐答案

没有实际的工作代码,我们只能推测为什么。

Without actual working code we can only speculate as to why.

如果你发送相同的图像一遍又一遍,你每次都在做一个新的形象。这不好。您可以这样做:

If you're sending the same image over and over you're making a new image every time. This is bad. You'd want to do something like this:

var images = {}; // a map of all the images

ws.onmessage = function(evt)
{
    var received_msg = evt.data;
    var display_image;
    var src = 'data:image/bmp;base64,'+received_msg;
    // We've got two distinct scenarios here for images coming over the line:
    if (images[src] !== undefined) {
      // Image has come over before and therefore already been created,
      // so don't make a new one!
      display_image = images[src];
      display_image.onload = function () {
          context.drawImage(this, 0, 0);
      }
    } else {
      // Never before seen image, make a new Image()
      display_image = new Image();
      display_image.onload = function () {
          context.drawImage(this, 0, 0);
      }
      display_image.src = src;
      images[src] = display_image; // save it for reuse
    }
}

写的(我复制的onload代码,例如,我不检查看看是否一个图像是否已经完成)。我会把这些部分留给你,但你会得到想法。

There are more efficient ways to write that (I'm duplicating onload code for instance, and I am not checking to see if an image is already complete). I'll leave those parts up to you though, you get the idea.

这篇关于Safari中的数据URI泄漏(是:使用HTML5画布的内存泄漏)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆