【问题标题】:Swapping image on canvas eats memory [duplicate]在画布上交换图像会消耗内存[重复]
【发布时间】:2016-08-13 03:23:34
【问题描述】:

我认为我遇到了与以下相关的问题: Systematically updating src of IMG. Memory leak

我没有足够的代表来评论答案,但https://stackoverflow.com/a/34085389/3270244 正是我的情况。

var canvasElement = $('canvas', camContainer);
var ctx = canvasElement[0].getContext('2d');
var image = new Image();
image.onload = function() {
  ctx.drawImage(this, 0, 0);
  image.src = '';
};

//for every getCamImg I receive exactly 1 image
socket.on('getCamImg', function(err, data) {
  if(data) {
    var dataImg = data.substring(data.indexOf(';') + 1);
    image.src = dataImg;
  }
  socket.emit('getCamImg');
});
socket.emit('getCamImg');

我每 1/10 秒更改一次 img.src(来自相机的 jpeg),我可以看到浏览器消耗越来越多的内存。 Firefox 停止在 500MB,Edge 停止在 100MB,对于 Chrome,我在 1G 附近停止测试。如果我删除 img.src 更改一切运行顺利(当然没有图像)。

我发现了很多(至少我是这么认为的)相关问题:

某处有人提到(对此感到抱歉:D)缓存可能是垃圾邮件,因为旧图像被保留。我不认为这是 gc 的问题,因为 chrome 有一个工具可以运行他并且没有任何变化。

谁能重现这个或以正确的方式指导我?

更新:

  socket.on('getCamImg', function(err, data) {
    if(data) {
      var image = document.createElement("img");
      image.onload = function() {
        ctx.drawImage(this, 0, 0, ctx.canvas.width, ctx.canvas.height);
        socket.emit('getCamImg');
        image.src = '';
      };
      image.src = dataImg;
    }
  });

这在 Firefox 中效果很好(image.src='' 很重要)。 Chrome 仍然泄漏。

【问题讨论】:

    标签: javascript image caching canvas memory-leaks


    【解决方案1】:

    我所做的几乎与您在我当前的项目中所做的一样。由于这对于评论来说太多了,我只是在答案中分享我的观察。我就是这样做的:

    var canvas = document.getElementById("canvas"),
        ctx = canvas.getContext("2d"),
    
        onNewImgData = function (data) {
            //create a new image element for every base64 src
            var img = document.createElement("img");
    
            //bind the onload event handler to the image
            img.onload = function () {
                //draw the image on the canvas
                ctx.drawImage(this, 0, 0);
                //do some stuff
                //...
                //done, request next image
            };
    
            //update the image source with given base64 data
            img.src = "data:image/bmp;base64," + data;
        };
    

    我没有清理任何东西,并且在我的应用程序中看不到内存泄漏(无论使用哪种浏览器)。但是我之前遇到过内存泄漏,因为我将所有 base64 数据都记录到了浏览器控制台中 :) 这导致了与您描述的完全相同的问题。

    【讨论】:

    • 好的,只是为了清楚。您每秒执行多次(img.src = ... 部分)? console.log 的想法很好,但我先检查了这个:D
    • 没错。每次我从我的 websocket 收到新的图像数据时,我都会调用上述函数。在我当前的实现中,这适用于高达 20FPS 的速度。没有任何泄漏。
    • 你在 chrome 中检查过这个吗?对不起,我看不出根本的区别:/
    • 我想到的事情是:a) 是否在您显示完当前图像后实际上从您的服务器请求每张图像或b) 您的服务器是否只是将图像发送到您的客户端,没有不管他是否可以进行新的渲染?我正在做a),我会推荐它;)
    • 是的,它适用于 Chrome、Edge 和 FF。 Chrome 是我的主要浏览器,使用上述代码时,RAM 使用量很少接近 100MB。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多