Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 上下文上的多个drawimage()会产生内存泄漏_Javascript_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 上下文上的多个drawimage()会产生内存泄漏

Javascript 上下文上的多个drawimage()会产生内存泄漏,javascript,canvas,html5-canvas,Javascript,Canvas,Html5 Canvas,我正在从Image对象数组对画布执行多个drawImage()。在Firefox中,使用不同的图像调用几十次drawImage后,这会导致巨大的内存泄漏,这个过程可能需要1或2gb的Ram 画布和图像尺寸约为1080x608 基本上,我的代码如下所示: var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); var images = [...]; // Array of loa

我正在从
Image
对象数组对画布执行多个
drawImage()
。在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中删除
时,内存消耗保持不变

Chrome和Safari的行为是不同的,我怀疑这是Firefox中垃圾收集器的工作方式,有没有办法清除画布缓存或其他什么


下面是一个

尝试在测试工具中运行代码并进行一些更改。据我所知,问题在于渲染到画布的结果图像。尽管加载的图像的图像文件大小相当小,但生成的图像仍然是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中保存,每个图像占用了几乎1MB的空间,而不是原来的30K左右。每次调用drawImage时,内存都会相应地增加,而调用的图像以前从未绘制过

因此,假设每个图像都由Firefox保存在内存中,结果大约是370*900K,即328MB。我不确定这里还有什么需要改进的地方,但问题主要是图像转换。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);
            });
var canvas=document.getElementById('main-canvas');
var canvasProperties={
x:canvas.offsetWidth,
y:帆布。远视
};
var图像=[];
var imagesRange=[0369];
对于(var i=imagesRange[0];i imagesRange[0]){
当前帧--;
}否则如果(e.deltaY>0&¤tFrame
context.clearRect(0,0,canvas.width,canvas.height);图像数组有多大?@grillcsirke:它不会清除内存。@Prinzhorn:大约300个图像,相当大,但是当间隔不活动时,内存消耗不会增加:它只会在拉入画布时增加。不要使用setInterval——如果负担过重,它会导致堆栈失败。而是使用
requestAnimationFrame
。我尖刻的评论是:如果你把一头大象放在你的电脑上,你就不会奇怪为什么你的电脑运行得很差。也许可以将370幅图像转换成视频流,并在视频元素中显示。视频元素将以资源高效的方式控制预加载和缓冲,这是您无法手动完成的。如果您的设计需要较慢的播放速率,则可以控制播放速率。