Почему Chrome сохраняет анонимный объект MediaRecorder в памяти? - PullRequest
0 голосов
/ 24 октября 2018

После попытки понять, почему некоторые объекты моего веб-приложения были сохранены в памяти Chrome, я думаю, что я, возможно, сузил его до случая, когда в противном случае недоступный MediaRecorder объект будет сохранен браузером,Обратите внимание на следующий минимальный пример, который воспроизводит проблему:

new MediaRecorder(new MediaStream())

Я профилировал использование кучи на вкладке Память в Chrome и Chromium, а наличие объекта MediaRecorder в куче непереходный процесс - он существует до тех пор, пока я не захочу найти его в куче после выполнения вышеизложенного, он не исчезает.

Почему он там?Ничто не удерживает его, это пахнет ужасно для меня как ошибка.Для сравнения, Firefox своевременно освобождает объект MediaRecorder, учитывая, что сборка мусора, конечно же, происходит, по крайней мере, даже через кучу секунд после выполнения вышеупомянутого оператора, а не при его снимке.

Объект медиа-рекордера ни на что не ссылается и должен иметь наименьшее время жизни, которое у него может быть, однако он остается в памяти после снимка, который я делаю после очистки консоли (разработчики из Developer Tools for Chromeрекомендую очистить консоль перед созданием снимка кучи, поскольку первый может удерживать объекты, которые в противном случае были бы освобождены).

Я не могу найти какие-либо методы в классе MediaRecorder, которые бы указывали на то, что можноотделить его от потока или иным образом «закрыть».Если не считать, что на него нет явных или не очень очевидных (например, через слушателей событий) ссылок, я могу только надеяться, что анонимный объект не сохраняется, а такие объекты обычно не являются, но MediaRecorder объектыпохоже.Похоже, для меня не существует какого-либо рычага, который можно было бы использовать, чтобы избавиться от него.

На приведенном ниже снимке экрана видно, что объекты, сохраняющие рекордер, не являются частью моих сценариев.скорее, они связаны с некоторым внутренним состоянием браузера:

Screenshot of Memory pane in the Chrome Developer Tools

Значок окна рядом с объектом, выбранным в столбце «Конструктор», имеетвсплывающая подсказка «Пользовательский объект [доступен] из окна».Приведенный выше фрагмент кода - это единственный код, который я запускаю на вкладке. Почему объект может быть доступен из окна, и если это так, это, безусловно, не может быть ссылками, которыми я управляю?

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

Как я уже говорилЯ выполнил ту же инструкцию в Firefox 62.0.2, и там поведение такое, как я и ожидал - один созданный объект MediaRecorder, похоже, выходит из области видимости (как и должно быть, так как он не должен иметь ссылок на него)вскоре после его создания.

(версия Chrome 69.0.3497.100, x64 в Windows 10)

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Согласно спецификации :

Объект MediaStream считается активным, когда у него есть хотя бы один MediaStreamTrack, который не завершился.MediaStream, который не имеет никаких дорожек или имеет только дорожки, которые закончились, неактивен.

При создании нового MediaStream, если вы не остановите все его дорожки, он остается в active state.

Итак, чтобы сбросить этот объект, вам нужно явно избавиться от его объектов MediaStreamTrack, получив ссылку на поток, например:

var myRecorder;
navigator.mediaDevices.getUserMedia({ 
  video: true,
  audio: true
}).then(function create_media_recorder(stream) {
  myRecorder = new MediaRecorder(stream);
  console.clear();
});

var myStream = myRecorder.stream;
myStream.getTracks().forEach(function(el) {
    el.stop()
}

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

Проверьте эти API для дальнейшего использования

https://developer.mozilla.org/en-US/docs/Web/API/MediaStream

https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack

0 голосов
/ 31 октября 2018

Убедитесь, что в настройках вашего браузера отключен параметр «Сохранить журнал при навигации», в противном случае console.clear () ничего не делает.

https://developer.mozilla.org/en-US/docs/Web/API/Console/clear

РЕДАКТИРОВАТЬ:

Кроме того, я сомневаюсь, что это утечка памяти, так как недоступные объекты автоматически удаляются.Более вероятно, что MediaRecorder сохраняет объекты в глобальной области видимости.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#Garbage_collection

"4.3.1 Жизненный цикл и поток мультимедиа" должны немного прояснить ситуацию.

https://www.w3.org/TR/mediacapture-streams/#stream-api

...