Скрипт действий 3: Утечка памяти в приложении для презентации опроса сервера

Я создаю инструмент удаленной презентации в AS3. Короче говоря, один пользователь (докладчик) имеет доступ к HTML-странице «оглавления» со ссылками на каждый слайд в презентации, а произвольное количество зрителей может смотреть презентацию на другой странице, которая, в свою очередь, находится в форма SWF, который каждую секунду опрашивает сервер, чтобы убедиться, что он находится на правильном слайде. Всякий раз, когда администратор щелкает ссылку слайда в оглавлении, база данных обновляется, и при следующем запросе SWF-файл презентации сравнивает метку слайда, отображаемого в данный момент, с ответом, полученным от сервера. Если ответ отличается от текущей метки, swf просматривает временную шкалу, пока не найдет правильную метку кадра; в противном случае он ничего не делает и ждет следующего результата опроса (через секунду).

Каждый слайд состоит из фрагмента ролика с собственной вложенной временной шкалой, которая зацикливается, пока отображается слайд. Нет сценария действий, управляющего каким-либо вложенным мувиклипом, и нет никакого сценария действий на основной временной шкале, кроме stop();s на каждом ключевом кадре (каждый из которых является слайдом в презентации).

Все построено и работает отлично. Единственное, что настораживает, это то, что если презентационный swf открыт достаточно долго (скажем, 20 минут), то опрос начинает заметно влиять на частоту кадров мувиклипов, анимируемых на том или ином слайде. То есть каждую секунду происходит заметное падение частоты кадров анимации, которая длится около трех десятых секунды, что довольно заметно (и, следовательно, является нарушением условий для всего набора презентаций!).

Я знаю, что в AS3 есть проблемы с управлением памятью, и я старался быть усердным в повторном использовании объектов и прослушивателей событий. Сам код предельно прост; есть экземпляр Timer, который срабатывает каждую секунду, что вызывает загрузку new URLRequest экземпляром URLLoader. URLLoader повторно используется от вызова к вызову, а URLRequest — нет (его необходимо каждый раз инициализировать новым значением уничтожения кеша, полученным из вызова new Date().time). Единственными объектами, созданными во всем классе, являются Timer, URLLoader, различные URLRequests (которые должны быть удалены сборщиком мусора), и единственными прослушивателями событий являются Timer (добавлены один раз), URLLoader (добавлены один раз) и подпрограммы, которые перемещаются назад и вперед по временной шкале, чтобы найти правильный слайд (и они удаляются, как только правильный слайд найден).

Я использую пакет статистики мистера Дуба для мониторинга использования памяти, что определенно со временем увеличивается, поэтому где-то должна быть утечка (она увеличивается с ~ 30 МБ изначально до> 200 МБ после некоторой очистки и около 25 минут безотказной работы).

У кого-нибудь есть идеи относительно того, что может быть причиной проблем с производительностью?

ОБНОВЛЕНИЕ: я не совсем уверен, что проблемы с производительностью напрямую связаны с памятью; Я запускал экземпляр презентационного swf примерно на 15 минут, и хотя использование памяти увеличилось только до 70 МБ (и осталось там), с интервалом в одну секунду начала появляться заметная икота, совпадающая с вызовами опроса (отслеживается с помощью панели Firebug Net). ). Что еще может вызвать заикание видеоклипов?


person justinbach    schedule 22.02.2010    source источник
comment
Можешь сбросить кучу и посмотреть, что именно там висит?   -  person Anon.    schedule 23.02.2010
comment
Забавно, у меня была точно такая же проблема. Мы опрашиваем данные каждую минуту или около того, чтобы обновить некоторую информацию (которая оказывается временной шкалой). Через несколько часов флэш-память съест от 300 МБ до 1 ГБ. Мы не нашли решения.   -  person Erix    schedule 23.02.2010
comment
просто понятия не имею, о чем думать, кроме видео, которое я видел сегодня утром :) fdt.powerflasher.com/developer-tools/fdt-3/fdt-4-beta/ профилировщик выглядит как удобная функция для проверки вашего приложения и просмотра того, что происходит внутри.   -  person a--m    schedule 23.02.2010
comment
+1 купол прав. если вы можете получить копию flex builder/flash builder, вы можете запустить профилировщик и получить хороший контроль над потреблением памяти вашими приложениями. настоятельно рекомендуется.   -  person heavilyinvolved    schedule 23.02.2010


Ответы (2)


Я знаю, что это немного запоздало, но я часто использую профилировщик Flash Builder и обнаружил, что TimerEvent генерируется классом таймера.

  1. использует довольно много памяти по отдельности и
  2. кажется, не освобождается должным образом во время сборки мусора (даже если вы остановили таймер и удалили все ссылки на него).

Новое событие генерируется для каждого Timer тика. Вместо этого я использую setInterval, хотя некоторые евангелисты AS3, кажется, не рекомендуют это делать. Я не знаю почему. setInterval по-прежнему генерирует события таймера, но со временем они, похоже, должным образом очищаются от мусора.

Таким образом, одна из стратегий может заключаться в том, что

  1. вы заменяете Timer вызовом setInterval() ... который, возможно, в любом случае является более надежным кодом, и
  2. (ВНИМАНИЕ) принудительная сборка мусора при каждой очистке слайдов (но не при каждом опросе). Подробнее о плюсах и минусах см. в этом вопросе.

Второе предложение является лишь временной мерой. Я настоятельно рекомендую вам использовать инструменты профилирования, чтобы найти утечку. Flash Builder Pro имеет 60-дневную пробную версию, которая может помочь.

Наконец, при переходе к совершенно новому SWF-файлу слайда (а не к новой позиции временной шкалы на текущем слайде) как убедиться, что предыдущий SWF-файл слайда выгрузился правильно? Или я неправильно понимаю ваши настройки, и есть только один реальный слайд SWF?

person Thomas Jung    schedule 19.04.2010
comment
Спасибо за ответ, Томас. Я загрузил пробную версию Flash Builder, и она оказалась полезной; Я дам вам знать, что я найду. И да, на самом деле есть только один SWF-файл слайда, так что не стоит беспокоиться о том, что предыдущий слайд не выгрузился должным образом. - person justinbach; 21.04.2010

Только две вещи, которые пришли мне в голову:

  • В зависимости от версии проигрывателя Flash и загрузки процессора сборка мусора иногда не запускается до того, как будет израсходовано 250 МБ (или даже больше) памяти.
  • Мувиклипы, спрайты, загрузчик и все, что прослушивается Eventlistener, не будут уничтожены сборкой мусора.

Итак, я считаю, что ваша проблема в том, что либо слайды, либо загрузчик не очищаются правильно после того, как вы их использовали, поэтому они остались в памяти.

Хороший повод начать читать: http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

person TheHippo    schedule 26.02.2010