Javascript绘制画布内存泄漏

Javascript绘制画布内存泄漏,javascript,memory,canvas,memory-leaks,draw,Javascript,Memory,Canvas,Memory Leaks,Draw,这个脚本无休止地占用所有浏览器的内存。我不明白为什么 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var particles = [], amount = 5; var x = 100; var y = 100; var W, H; var p, gradient; //dimensions if(window.innerHeight){ W = window.

这个脚本无休止地占用所有浏览器的内存。我不明白为什么

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var particles = [], amount = 5;
var x = 100; var y = 100;
var W, H;
var p, gradient;  

//dimensions
if(window.innerHeight){
    W = window.innerWidth, H = window.innerHeight;
}else{
    W = document.documentElement.clientWidth, H = document.documentElement.clientHeight;
}
canvas.width = W, canvas.height = H;


//array voor de meerdere particles
for(var i=0;i<amount;i++){
    particles.push(new create_particle());
}

function create_particle(){
    //random positie op canvas
    this.x = Math.random()*W;
    this.y = Math.random()*H;

    //random snelheid
    this.vx = Math.random()*20-10;
    this.vy = Math.random()*20-10;

    //Random kleur
    var r = Math.random()*255>>0;
    var g = Math.random()*255>>0;
    var b = Math.random()*255>>0;
    this.color = "rgba("+r+", "+g+", "+b+", 0.5)";
    this.radius = Math.random()*20+20;

}

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

function draw(){
    canvas.width = canvas.width;
    canvas.height = canvas.height;
    //achtergrond tekenen
    //ctx.globalCompositeOperation = "source-over";
    //ctx.fillStyle = "rgba(0,0,0,0.5)";
    ctx.fillRect(0, 0, W, H);
    //ctx.globalCompositeOperation = "lighter";

    //teken cirkel
    for(var t=0; t<particles.length;t++){
        p = particles[t];

        //gradient
        gradient = ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,p.radius);
        gradient.addColorStop(0,"white");
        gradient.addColorStop(0.4,"white");
        gradient.addColorStop(0.4,p.color);
        gradient.addColorStop(1,"black");
        ctx.beginPath();
        ctx.fillStyle = gradient;
        ctx.arc(p.x,p.y,p.radius,Math.PI*2,false)
        ctx.fill();

        //beweeg
        p.x+=p.vx;
        p.y+=p.vy;

        //canvas boundery detect
        if(p.x < -50)p.x = W+50;
        if(p.y < -50)p.y=H+50;
        if(p.x > W+50)p.x = -50;
        if(p.y > H+50)p.y = -50;
    }
}

(function animloop(){
    canvas.width = canvas.width;
    canvas.height = canvas.height;
    requestAnimFrame(animloop);
    draw();
})();


//resize?
function resizeCanvas(){ 
    canvas.height = W; 
    canvas.width = H;
    ctx.fillRect(0, 0, W, H);
}
if(window.addEventListener){
     window.addEventListener('resize', resizeCanvas, false);
}else{
     window.attachEvent('resize', resizeCanvas);
}
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
变量粒子=[],数量=5;
var x=100;变量y=100;
var W,H;
var p,梯度;
//尺寸
if(窗内高度){
W=window.innerWidth,H=window.innerHeight;
}否则{
W=document.documentElement.clientWidth,H=document.documentElement.clientHeight;
}
canvas.width=W,canvas.height=H;
//voor de meerdere粒子阵列
对于(var i=0;i>0;
var g=Math.random()*255>>0;
var b=Math.random()*255>>0;
this.color=“rgba(“+r+”,“+g+”,“+b+”,0.5)”;
this.radius=Math.random()*20+20;
}
window.requestAnimFrame=(函数(){
return window.requestAnimationFrame | |
window.webkitRequestAnimationFrame | |
window.mozRequestAnimationFrame | |
window.oRequestAnimationFrame | |
window.msRequestAnimationFrame | |
函数(回调){
设置超时(回调,1000/60);
};
})();
函数绘图(){
canvas.width=canvas.width;
canvas.height=canvas.height;
//阿奇特格隆德泰肯酒店
//ctx.globalCompositeOperation=“源代码结束”;
//ctx.fillStyle=“rgba(0,0,0,0.5)”;
ctx.fillRect(0,0,W,H);
//ctx.globalCompositeOperation=“打火机”;
//特肯·西克尔
对于(VarT=0;Tw+50)p.x=-50;
如果(p.y>H+50)p.y=-50;
}
}
(函数animloop(){
canvas.width=canvas.width;
canvas.height=canvas.height;
请求动画帧(animloop);
draw();
})();
//调整大小?
函数resizeCanvas(){
canvas.height=W;
canvas.width=H;
ctx.fillRect(0,0,W,H);
}
if(window.addEventListener){
addEventListener('resize',resizeCanvas,false);
}否则{
window.attachEvent('resize',resizeCanvas);
}
我试图更改一些代码(这也是最终版本),但仍然会泄漏。如果您使用此脚本并观看“taskmanager”或在浏览器内存中检查,您会发现它会缓慢且持续地消耗内存


编辑:在添加canvas.height解决方案并移动一些脚本后,脚本仍然会泄漏!我必须说Firefox的泄漏看起来比Chrome更严重!

在开始另一组绘图之前,请尝试清洁画布。您可以通过再次设置其宽度和高度来清除它

以下是一些定向代码:

function draw() {
   canvas.width = canvas.width;
   canvas.height = canvas.height;

   /* draw */
}
你有:

   canvas.width = canvas.width;
    canvas.height = canvas.height;
我猜这与clearRect的功能相同……但一定要尝试一下:

function draw(){

   ctx.clearRect ( 0 , 0 , canvas.width , canvas.height );

   /* draw */
}

看看是否有任何变化。

我猜你的创建粒子函数可能会泄漏,但我不确定如何泄漏,一个想法是创建一个内部对象,而不是使用

function create_particle(){
  return {
    x: Math.random()*W,
    y: Math.random()*H,
    vx: Math.random()*20-10,
    vy: Math.random()*20-10,
    r: Math.random()*255>>0,
    g: Math.random()*255>>0,
    b: Math.random()*255>>0,
    color: "rgba("+r+", "+g+", "+b+", 0.5)",
    radius: Math.random()*20+20,
  };
}

我不确定这是否是问题所在,但这似乎是我唯一能想到的事情,看起来有点奇怪,

不要使用任务管理器。使用Firefox和about:memory选项卡,这样你就可以准确地报告内存的使用情况。这只是一个参考,因为即使在那里,它也不仅仅是可见的。但是谢谢提示:)嗨。除了“gradient中存在内存泄漏”之外,你找到了答案吗?没有,我还没有找到解决方案:(createRadialGradient在Firefox 77.0b9中也有内存泄漏,但在Chrome或Edge中没有。All Win 7。当我直接尝试这一点时,我的第一个结论是,这不是解决方案(