在消耗大量内存后,浏览器在创建图像Blob的ObjectURL时抛出错误

Browser throws error on creating an ObjectURL of an Image Blob after consuming lot of memory

本文关键字:Blob ObjectURL 错误 出错 图像 浏览器 内存 创建      更新时间:2023-10-27

嗯,我在编程一个通过WebSockets从服务器接收图像的Web应用程序时遇到了一个奇怪的错误。服务器每秒向浏览器发送大约8张图像(.bmp)。每个图像的大小约为300KB。这大约是2.4Mbps。

浏览器以二进制blob:的形式接收图像

//WebSocket
var ws = new WebSocket("ws://192.168.0.10:1337");
//Image
var camImg = new Image();
ws.onmessage = function(msg)
{
    var data = msg.data;
    // handle binary messages from server
    if (data instanceof Blob) camImg.src = window.URL.createObjectURL(data);
};
camImg.onload = function()
{
    //draw image to canvas
    canvasCont2D.drawImage(this,0,0);
    //request next frame
    ws.send("give me the next image!");
    //delete ObjectURL
    window.URL.revokeObjectURL(this.src);
};

所以在这之前一切都很顺利。现在我来解决第一个问题:当我在Chrome中测试这一点时,我在TaskManager上查看了这一编码需要多少资源。我看到了Chrome的一个进程,它的启动内存大约为90MB。每秒钟都会增加2.4MB。所以看起来我收到的每一张图片都会留在内存中。有没有可能防止这种情况发生?收到的斑点似乎在Chrome开发工具的资源下,顺便说一句,

无论如何,这个问题让我想到了第二个问题:这个过程的内存消耗不断增加,在大约400-500MB的时间后,它被刷新,在90MB时再次开始,再次增加。这么久了,这只是一个记忆问题。但有时可能会发生这样的情况,即内存没有被刷新,并上升到大约600MB。在这一点上,我没有收到任何新的图像。控制台显示一个错误,上面写着:

加载资源失败:服务器响应状态为404(未找到)

此错误发生在以下行:

camImg.src = window.URL.createObjectURL(data);

目前,我通过捕捉错误事件来解决这个问题:

camImg.onerror = function()
{
    //request next frame anyway and wait for memory flush
    ws.send("give me the next image!");
};

所以我只是请求新的图像,因为一段时间后,内存再次刷新(几秒钟后),我可以接收新的图像。

使用Opera也会出现同样的问题。我想这主要是内存消耗的问题。也许是浏览器中的错误?还是我在编程上犯了一个大错误?

我将非常感谢任何帮助,因为我不知道是什么导致了这个问题。。。

OS:Windows7 64位

Chrome版本35.0.1916.153 m

Chrome版本38.0.2068.0金丝雀(64位):(chrome://flags/#impl-侧涂设置没有区别)。

在我正在做的一个原型中,我得到了与chrome 35和最近的金丝雀版本完全相同的行为。在IE和firefox中可以。我正在运行一个本地主机c++websocket服务器,大约每秒10帧,图像为0.5MB。chrome内存最终上升,一些东西也破坏了chrome。

前进:

1) 在image.onerror中,我调用window。URL.revokeObjectURL(this.src);这似乎解决了我的内存泄漏问题,但不是404。

2) 当在F12调试器下运行时,速度太慢了,我似乎没有遇到问题。因此,在页面上,我有3个计数器:1)Blob接收计数,2)image.onload计数和3)image.onerror计数。在大约900次成功加载后,我开始出现加载故障。然后,在经历了50次失败之后,我又开始获得成功的负载。这种模式不断重复,但数字似乎是随机的。(这一切似乎有点GC相关的问题,但只是基于经验的预感)。

3) 我可以通过更改ws.binaryType='arraybuffer'来修复(又名"bodge")这个问题。我需要一个blob,所以我基于新的Uint8Array(msg.data)构建了一个新的blob。一切都很好,根本没有加载失败。

我在这里做了一个不必要的二进制副本,但它似乎没有任何明显的速度差异。我不能100%确定这里发生了什么以及修复的稳定性。

互联网上大多数类似的图像加载示例都没有oneror处理程序。在我的机器上运行这样的例子会导致无法解释的内存泄漏。除非在调试器下,否则你不会看到404。互联网上有很多人抱怨加载图像时内存泄漏。也许它有关联。

我将在铬论坛上提出这个问题。

希望这能帮助。。。无光泽