Как предотвратить утечку памяти путем очистки <audio>элементов? - PullRequest
4 голосов
/ 05 декабря 2010

Я написал немного JavaScript с помощью jQuery, который загружает звуковой файл с тегом HTML 5 <audio> и, щелкнув мышью, начинает воспроизводить новый экземпляр этого звукового файла (чтобы он мог воспроизводиться несколько раз параллельно / наложение).

HTML:

<audio id="audiotemplate" src="audio/myfile.ogg"></audio>

JavaScript:

mybutton.click(function() {
    $('#audiotemplate').clone()[0].play();
});

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

РЕДАКТИРОВАТЬ: Для быстрого теста лучше использовать $(document).keypress вместо mybutton.click и держать кнопку нажатой.

Как очистить элемент <audio> после завершения воспроизведения звукового файла?

ПРИМЕЧАНИЕ: Я не вставляю клонированный элемент в страницу.

ПРИМЕЧАНИЕ 2: Утечка также происходит, если вы щелкнете, подождите, пока не закончится звук, кликните снова ...

(Я доволен решением, но также ценю объяснение, почему утечка вообще происходит.)

1 Ответ

2 голосов
/ 05 декабря 2010

Работает ли это лучше?

mybutton.click(function() {

    var cloned = $('#audiotemplate').clone()[0];

    cloned.play();

    cloned.onended = function() {
        $(cloned).remove();
    }

});

Здесь, на JSFiddle.

Я могу только догадываться о утечке, и это означает, что некоторая память зарезервирована длякаждый экземпляр, который вы клонируете, и когда он заканчивается, не очищается автоматически, потому что вам может понадобиться снова получить к нему доступ.Например, ваш браузер не знает, что вы хотите, чтобы он воспроизводился только один раз, поэтому он будет сохраняться, потому что вы можете захотеть снова вызвать play().

Использование jQuery'sremove() должен освободить эту память.

Обновление

Сколько раз вы клонируете ее?Вы знаете, что это браузер, и, вероятно, не оптимизирован для одновременной работы сотен audio элементов?

Я только что клонировал его ~ 300 ~ 600 раз в Firefox 3.6 ибежал нормально.Однако после нескольких сотен на Chrome 8 он вылетел.

Здесь происходит клонирование через setInterval(). Не нажимайте , если вы думаете, что он сломает ваш браузер.

Обновление

@ alex: Нет, не одновременно.Моя проблема в том, что Chromium пропускает память, даже если звук короче интервала респауна (как в примечании 2), поэтому не воспроизводится одновременно, но после друг друга.

Это все еще приводит к краху ваших браузеров?

...