2014-11-06 2 views
1

Я пытаюсь понять, почему память продолжает накапливаться в Chrome (версия 38.0.2125.111) при рисовании изображений на холсте HTML5. Используя приведенный ниже код, я наблюдаю, как цифра «Память» для моей вкладки в диспетчере задач Chrome увеличивается примерно на 300-400 кб в секунду до где-то между 35 МБ и 50 МБ, прежде чем опуститься примерно до 5 МБ. После этого происходит один раз, по мере продолжения процесса память просто продолжает подниматься и подниматься (т. Е. Он неров, кажется, снова очищается). Если я снова нажму «Go» или даже если обновить страницу, то память не исчезнет вообще.Увеличение объема памяти до Canvas

<!DOCTYPE HTML> 
 
<html> 
 
    <head> 
 
     <script type="text/javascript"> 
 
      function tryit() { 
 
       var px=1; 
 
       var py=1; 
 
       var canvas = document.getElementById('myCanvas'); 
 
       var context = canvas.getContext('2d'); 
 
       var canvas2 = document.getElementById('myCanvas2'); 
 
       var context2 = canvas2.getContext('2d'); 
 
       var img=document.getElementById("img1"); 
 
       var thereps=document.getElementById("txtreps").value; 
 
       
 
       context2.drawImage(img,0,0); 
 

 
       var counter=1; 
 

 
       function loop() { 
 
        counter=counter+1; 
 
        px=Math.random()*1000; 
 
        py=Math.random()*800; 
 
        
 
        context.drawImage(canvas2, 0, 0, 10, 16, px,py,10,16); 
 
        if (counter>=thereps) { 
 
         clearInterval(myTimer); 
 
         context.clearRect(0,0,1034,814); 
 
         alert("done"); 
 
        } 
 
       } 
 
       myTimer = setInterval(loop,17); 
 
      } 
 
     </script> 
 
    </head> 
 
    <body> 
 
     Loop: 
 
     <input id="txtreps" type="text" size="6" value="10000"/> 
 
     times 
 
     <input type="button" onclick="tryit();" value="Go"/> 
 
     
 
     <div style="position:relative;width:1034px;height:814px;border:1px solid grey;"> 
 
      <canvas id="myCanvas" width="1034" height="814" style="visibility: visible; position: absolute; top:0; left: 0;border:1px solid black;" ></canvas>   
 
      <canvas id="myCanvas2" width="10" height="16" style="visibility: hidden;position:absolute; left:0px; top:0px;border:1px solid red;" ></canvas> 
 
      <img id="img1" src="untitled.png" width="10" height="16" style="visibility: hidden; position: absolute; top:0; left: 0;border:1px solid green;"> 
 
     </div> 
 
    </body> 
 
</html>

Это микро пример того, как мои большие работы приложения. Пользовательский ввод запускает анимацию для запуска, и они обычно работают в течение максимум 5 секунд, а затем останавливаются. Затем пользователь снова вводит ввод для запуска другой анимации. Это можно повторить сотни раз. Поскольку у меня больше изображений, я нахожу, что память увеличивается со скоростью 3-4 МБ в секунду, и вскоре я нажимаю ошибку Aw Snap, так как память получила более 1,4 ГБ. Я делаю что-то неправильно? Есть ли способ заставить процесс «очистить», который браузер, похоже, применяет еще раз?

Обратите внимание, что когда я устанавливаю свой цикл с использованием requestAnimationFrame вместо таймера, я обнаруживаю, что увеличение памяти происходит, даже если я на самом деле ничего не рисую (т. Е. Не делаю ни одного вызова drawImage).

+0

Я думаю, что вы правы (ссылка на мой удаленный ответ), это скорее всего ошибка в текущей версии. Вы могли бы ответить на это сами и отметить его как правильный ответ. – K3N

ответ

0

Это похоже на потенциальную ошибку в текущей версии Chrome. Я поставил вопрос с Google в надежде, что это будет разрешено.

Спасибо за помощь.

0

Вы должны использовать RAF, setInterval действительно должен быть вашим последним прибежищем, потому что он запустит браузер, пытаясь сохранить цикл вовремя. Take a look here if that makes no sense.

Вместо этого, если вы не можете использовать RAF, используйте setTimeout.

Обратите внимание, что, когда я установил свой цикл с использованием requestAnimationFrame вместо таймера, я считаю, что увеличение памяти происходит, даже если я не на самом деле сделать что-нибудь (то есть я не делаю DrawImage вызова).

Это неизбежно, так как при выполнении происходит вызов функции (стек, параметры и т. Д.). Но с RAF, GC должен ударить в нужное время (во избежание рывка) в большинстве современных браузеров и очистить данные old-generation.

+0

Спасибо за это. Когда я вместо этого использую RAF, я вижу то же самое поведение. Кажется, что он очищается один раз, когда он впервые попадает в память 35 Мбайт, и после этого кажется, что он просто накапливает все больше и больше памяти, даже не очищаясь. – rufus

+0

Вы делаете там серьезную работу, а блинчивый холст - дорогостоящая операция. Следовательно, это нормальное поведение. Я заинтригован. Что происходит, когда вы рисуете свой 'img' напрямую? – nullpotent

+0

Это тот же результат, если я рисую изображение напрямую.Я пытаюсь понять, почему при использовании RAF память увеличивается настолько и не очищается, даже если я вообще не делаю вызов DrawImage внутри цикла (так что все, что он делает в этом случае, перебирает и меняет значение несколько переменных). – rufus

Смежные вопросы