在消耗大量内存后,浏览器在创建图像Blob的ObjectURL时抛出错误
Browser throws error on creating an ObjectURL of an Image Blob after consuming lot of memory
嗯,我在编程一个通过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。互联网上有很多人抱怨加载图像时内存泄漏。也许它有关联。
我将在铬论坛上提出这个问题。
希望这能帮助。。。无光泽
- Javascript/Jquery Blob not showing Chrome PDF
- 使用blob作为src图像
- 使用PHP,我如何将JSON blob附加到现有的多级JSON对象
- 从HTML表单发布blob的表单输入类型是什么
- 将大数组(字符串和类型数组的混合物)存储到blob或文件中/从blob或文件检索大数组的最佳方式
- 图像Blob>上传后是其大小的50倍
- createObjectURL blob url在Firefox中不安全
- 使用blob从ajax结果下载文件
- 将Excel BLOB转换为javascript数组
- html image blob to base64
- AudioContext从blob获取数据的视频创建MediaElementSource
- CSV、PDF、Excel文件在dataTables的导出扩展中作为blob下载
- 删除javascript中的大Blob
- Blob from DataURL?
- 内容安全策略指令:;脚本src'self'blob:文件系统:chrome扩展资源:“;获取是否时
- Javascript-将类型化数组保存为blob,并作为二进制数据读回
- Fin上传器直接上传到Azure Blob存储-在Javascript中获取文件uri
- 通过AJAX发送文件返回'blob'错误
- 从IE 11中的HTTP URL下载blob
- 在消耗大量内存后,浏览器在创建图像Blob的ObjectURL时抛出错误