2016-02-23 6 views
4

Fiddle: https://jsfiddle.net/eimmot/065wxa9o/9/Утечка памяти с Web Worker/Canvas

Использование Chrome, запустите диспетчер задач (Shift + Esc), нажмите на кнопку рабочий инвертировать несколько раз, каждый раз, когда он идет вверх ~ 10 МБ. В любое время, когда я получаю сообщение от рабочего, память поднимается, это не изменение или доступ к холсту, это происходит, когда рабочий отправляет сообщение обратно в основной поток. Это становится все хуже, чем больше сообщение.

Добавление буфера ImageData в дополнительный переносчик список на postMessage не имеет значения, тот же результат, мне интересно, есть ли другой способ, которым я должен подходить к этому.

imageData = ctx.getImageData(0, 0, 800, 600); 
    worker.postMessage(imageData, [imageData.data.buffer]); 

Все еще не имеет значения, является ли основной поток и/или рабочий поток передачей права собственности. Я вижу на консоли, что объект imageData фактически передает право собственности, но память все еще увеличивается! Я пробовал профилирование памяти с помощью инструментов chrome dev, но я не вижу, где это увеличение.

Принуждение GC в инструментах dev очищает память. Иногда GC запускается автоматически, иногда это не так, когда он это делает, он выпускает только 10% от того, что было выделено.

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

Передаваемые объекты: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects)

Обновление

Chrome версии 48.0.2564.116 бета-м (64-разрядная версия)

Fiddle: https://jsfiddle.net/eimmot/065wxa9o/13/

Добавлена ​​опция цикла, кажется, единственный способ освободить память - это прекратить поток, я хотел бы избежать создания новых потоков каждый раз, хотя и просто держать один открытым, потому что есть заметная задержка при создании нового каждый раз, когда

+1

Я думаю, вы должны [сообщить об ошибке] (https://support.google.com/chrome/answer/95315?hl=en) с Chrome люди. В диспетчере задач вы можете щелкнуть правой кнопкой мыши и добавить столбец «JavaScript-память». Вы заметите, что в то время как фактическая память, используемая на вкладке, увеличивается, объем памяти, используемой для Javascript, остается прежним. Это, кажется, указывает на проблему вне вашего контроля (по крайней мере, из моего понимания). –

ответ

1

Я нашел решение, которое работает для меня в Chrome.Я сделал два основных изменение в обхвате версию вашей скрипки:

  1. Добавить imageData.data.buffer в список передачи при возвращении его из рабочего
  2. прохода вокруг типизированного массива, imageData.data, вместо всего объекта ImageData

Вот модифицированная скрипка: https://jsfiddle.net/065wxa9o/14/

Обратите внимание, что просто добавления буфера передачи лития работника st не работает (https://jsfiddle.net/065wxa9o/15/) Мне нужно передать только типизированный массив.

Chrome версии 52.0.2743.116 (64-разрядная версия)

+0

Ни одна из этих версий не работает для меня на Firefox - если у кого-то есть решение для меня, мне было бы очень интересно. – TheNeuralBit

2

У вас нет утечки памяти. Это просто нормальное поведение GC, и вы не можете сделать это, чтобы остановить чрезмерное использование памяти.

я имел игру с изменением коды вашей скрипкой, так что функция worker.onmessage сразу называется startWork, эффективно положить его в петле, отправить данные, получить перевернутый набор данных, поместите его на холсте, а затем вызвать startWork снова и пусть это уйдет, пока я выпью кофе. Все прошло отлично.

Наблюдение за процессами на chrome 49.0.2623.47 beta-m Использование памяти выглядело примерно в 110 МБ, но никогда не заканчивается. Оба распределения кучи и временная шкала показывают нормальное поведение и отсутствие утечек. Chrome внес некоторые изменения в GC, чтобы он отменил свои действия в пользу DOM и Javascript, которые, если вы не привыкли к этому, выглядят так, как использование памяти выросло, о чем не о чем беспокоиться. Все, что имеет значение, - это то, что когда вам нужна память, она доступна. GC очистит, если критическая низкая память, и лучше иметь некоторую мертвую память, а не блокировать DOM или Javascript, когда они заняты, просто чтобы сбросить некоторую ненужную память.

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