2015-10-05 2 views
-1

У меня есть 2 canvas элементов, и я рисую их в интервале 125 мс.HTML5 Проблема с потерей памяти холста

Оба они должны быть полностью перерисованы из-за характера их работы, поэтому невозможно увеличить только некоторые части из них, чтобы повысить производительность.

Проблема

Когда я вижу в диспетчере задач, Рабочая Set (Memory) постоянно увеличивается, на основе того, насколько быстро я перерисовывая холсты.

То, что я пытался до сих пор

  1. Используйте clearRect для очистки (в отличие, чтобы установить это снова ширина)

  2. Пробовал удалить родительский DIV холста и воссоздании DIV и загрузка холст в нем: это помогает замедлить увеличение памяти, но не полностью ее останавливает.

  3. Уменьшение различных context.fills как можно меньше, но опять же из-за природы холста, у него все еще есть много таких.

Даже если я все это делаю, рабочий набор может быть высоким, но не должен постоянно увеличиваться.

Любые предложения по управлению утечкой памяти?


Обновление: Утечка не в полотне чертежи. Я использую веб-исполнителя для передачи данных на холст, который где-то протекает. Извините за путаницу!

+1

Tough знать, не видя кода, хотя JS утечки памяти часто вращается вокруг неснятых слушателей событий. Что касается проблемы с переутомлением, вы можете сложить несколько холстов друг на друга и перерисовать только те, которые в ней нуждаются (хотя пользователь может взаимодействовать только с верхним слоем). Я бы предположил, что вы, возможно, создаете закрытие в своем перерисовке fn и переназначение ваших данных изображения на повторное количество закрытых локальных варов. –

+0

«Оба они должны быть полностью перерисованы из-за характера их работы» Вы уверены, что не можете разобрать рисунки на нескольких холстах, которые не нужно обновлять в каждом кадре? Таким образом, вы можете просто использовать 'drawImage()', который является одним из самых быстрых методов на холсте. – Kaiido

+0

Точка @JaredSmith стоит копать. Мне также интересно, если вы думаете об использовании beginPath: вы знаете, что если вы этого не сделаете, путь будет расти? Показать код, потому что в противном случае это трудно сказать. – GameAlchemist

ответ

3

Использование clearRect - ваш лучший выбор.

Почему вы с помощью 125 мс перерисовывать против requestAnimationFrame (это использует родной клеща, который позволит также потери кадров и помочь с производительностью)

Я хотел бы избежать удаления DOM элементов, как это довольно дорого.

Память всегда будет расти, я также проверил бы ваши замыкания, так как все, что не закрыто, не будет автоматически собираться мусором, что приведет к большему использованию памяти.

Оформить заказ на номер statsjs, который расскажет вам ваш FPS и даст вам что-то, что нужно для графика. также Memory Stats, который покажет вам потребление памяти.

Мое предположение о том, почему вы видите такой всплеск, заключается в том, что ресурсы не собираются в мусор, и ваш код может использовать некоторые оптимизации, но не видя ничего, что является большим выстрелом в темноте.

+0

IIRC не совсем верно, что закрытые лексические переменные не могут быть собраны в мусор (хотя это, безусловно, более проблематично). Но я подозреваю, что ты прав насчет источника утечки. И вы определенно находитесь на RequestAnimationFrame. –

+0

Да, это не ОГРОМНАЯ проблема, но может вызывать проблемы в зависимости от структуры кода и того, как все настраивается. Объект памяти замыкания - это предлагаемая оптимизация для создания вообще, а также для обработки большого количества вещей на холсте. –

+0

Да, особенно что-то довольно большое, как данные буфера изображения. –

0

Попробуйте обернуть цикл анимации другой функцией, которая инициализирует переменные. Таким образом, никакие переменные не создаются или не уничтожаются в цикле.

var aniTimeout = null; 
 

 
function wrap() { 
 
    
 
    var can = document.getElementById('can'); 
 
    var ctx = can.getContext('2d'); 
 
    var x = 0; 
 
    var y = 0; 
 
    var r = 5; 
 
    var colors = ["#FF0000","#009900","#0000FF","#990099","#00CCCC","#FFCC00"]; 
 
    var cLen = colors.length; 
 
    var ms = 125; 
 
    
 
    function ani() { 
 
    ctx.clearRect(0,0,50,200); 
 
    ctx.clearRect(0,0,200,50); 
 
    ctx.clearRect(150,0,200,150); 
 
    ctx.clearRect(0,100,200,150); 
 
    x = Math.floor(Math.random() * 190) + 5; 
 
    y = Math.floor(Math.random() * 140) + 5; 
 
    ctx.fillStyle = colors[Math.floor(Math.random() * cLen)]; 
 
    ctx.beginPath(); 
 
    ctx.moveTo(x, y); 
 
    ctx.arc(x,y,r,0,Math.PI*2); 
 
    ctx.fill(); 
 
    aniTimeout = setTimeout(ani,ms); 
 
    } 
 
    
 
    ani(); 
 
    
 
} 
 

 
wrap();
#can { 
 
    border:1px solid #999999; 
 
}
<canvas id="can" width="200" height="150"></canvas>

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