我正在从drawImage()
个对象的数组中对多个Image
做一个画布。在Firefox中,经过几十次不同图像的drawImage调用后,这会导致巨大的内存泄漏,这个过程最多需要1或2GB的Ram。
画布和图像尺寸约为1080x608
基本上,我的代码如下所示:
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var images = [...]; // Array of loaded image (new Image())
var currentImage = 0;
var interval = setInterval(function() {
context.drawImage(images[currentImage]);
currentImage++;
}, 50);
当我清除间隔时,几分钟后内存消耗会恢复正常。当我从DOM中删除<canvas>
时,内存消耗保持不变。
Chrome或Safari中的行为有所不同,我怀疑它是垃圾收集器在Firefox中的工作方式,是否有办法清除画布缓存或其他内容?
这是JSFiddle
答案 0 :(得分:0)
尝试在测试工具中运行代码并进行一些更改。据我所知,问题是关于渲染到画布的结果图像。尽管您加载的图像具有相当低的图像文件大小,但生成的图像仍为1280 x 720.即使我更改画布大小并修改您的drawImage调用也是如此...
context.drawImage(
images[currentFrame],
0, 0, images[currentFrame].width, images[currentFrame].height,
0, 0, canvas.width, canvas.height);
...它产生相同的1280 x 720图像,然后我可以从Firefox保存,每张图像占用近1 Mb,而不是原来的30K左右。每次使用之前未绘制的图像调用drawImage时,内存都会相应地增加。
因此,考虑到每个图像都由Firefox保存在内存中,这导致大约370 * 900K,即328 Mb。不知道还有什么在这里增加,但问题主要是图像转换。 Firefox存储了几个内存大小比压缩文件格式大得多的1280x720图像,因此内存分配有了巨大的飞跃。
我甚至在事件处理程序中移动了上下文抓取,它对内存分配没有影响。
忽略下面加载图像的部分,并根据onload事件设置图像。这可能导致图像不按顺序。我只是试着看看是否有任何关于图像未完全预装的问题。
var canvas = document.getElementById('main-canvas');
var canvasProperties = {
x: canvas.offsetWidth,
y: canvas.offsetHeight
};
var images = [];
var imagesRange = [0, 369];
for (var i = imagesRange[0]; i <= imagesRange[1]; i++) {
var image = new Image();
image.onload = function(event) {
images.push(event.target);
};
image.src = 'http://frames.teleport.ninja/frames/electrosanne/lowres1080/frame'
+ parseId(i) + '.jpg';
}
var currentFrame = 0;
canvas.addEventListener('wheel', function(e) {
var context = canvas.getContext('2d');
e.preventDefault();
if (e.deltaY < 0 && currentFrame > imagesRange[0]) {
currentFrame--;
} else if (e.deltaY > 0 && currentFrame < imagesRange[1]) {
currentFrame++;
}
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(
images[currentFrame],
0, 0, images[currentFrame].width, images[currentFrame].height,
0, 0, canvas.width, canvas.height);
});