Отображение ссылок на объекты Flex - PullRequest
4 голосов
/ 10 июня 2010

У меня есть небольшая проблема с утечкой памяти в моем приложении Flex, и короткая версия моего вопроса: есть ли способ (в AcitonScript 3) найти все живые ссылки на данный объект?

У меня есть несколько представлений с моделями презентаций за каждой из них (с использованием Swiz).Представления, представляющие интерес, являются дочерними элементами TabNavigator, поэтому, когда я закрываю вкладку, представление удаляется со сцены.Когда представление удаляется со сцены, Swiz устанавливает нулевую ссылку на модель в виде, как и должно быть.Я также удаляю AllChildren () из представления.

Однако при профилировании приложения, когда я делаю это и запускаю сборщик мусора, ни представление, ни модель представления не освобождаются (хотя оба устанавливают свои ссылки друг на друга на нуль).Один объект модели, используемый представлением (хотя и не презентатор), освобожден, поэтому он не полностью сломан.

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

Приветствия.

Ответы [ 3 ]

11 голосов
/ 11 июня 2010

Если вы используете Flex Builder, вы можете попробовать Profiler. По моему опыту, это не так хорошо для профилирования производительности, но очень помогло найти утечки памяти.

Это не самый интуитивно понятный инструмент, и ему нужно время, чтобы привыкнуть к нему (я имею в виду тот момент, когда он действительно становится полезным). Но, на мой взгляд, потраченное время, чтобы хотя бы изучить основы, окупается. Существует огромная разница между просмотром того, сколько памяти использует игрок в глобальном масштабе (что дает вам System.totalMemory, очень грубый, неточный и часто вводящий в заблуждение индикатор), и фактическим отслеживанием того, сколько экземпляров каждого объекта было создано, сколько еще осталось. живы и где они были размещены (так что вы можете найти потенциальную утечку в коде и фактически исправить ее, вместо того, чтобы полагаться на черную магию).

Я не знаю ни одного хорошего учебника для профилировщика FB, но, возможно, это поможет вам начать.

Сначала запустите профилировщик. Снимите флажок профилирования производительности и проверьте все остальное (включите профилирование памяти, просматривайте данные оперативной памяти и генерируйте трассировки стека выделения объектов).

Когда запустится профилировщик, вы увидите статистику об объектах приложения, сгруппированных по классам. На этом этапе вы можете настроить фильтры. Вы увидите много данных, и это очень легко быть пораженным. Пока что игнорируйте все, что есть во флэш-памяти и флексах, если это возможно, и сосредоточьтесь на каком-то объекте, который, по вашему мнению, должен быть собран.

Наиболее важными показателями являются "накопленные экземпляры" и "экземпляры". Первый - это общее количество созданных экземпляров; во-вторых, количество упомянутых экземпляров, которые все еще живы. Итак, хорошей отправной точкой является приведение вашего приложения в состояние, в котором создается представление, которое вы подозреваете, что утечки. Вы должны увидеть 1 для «накопленных экземпляров» и «экземпляров».

Теперь сделайте все, что вам нужно, чтобы добраться до точки, где это представление должно быть очищено (перейдите к другой части приложения и т. Д.) И запустите GC (для этого есть кнопка в пользовательском интерфейсе профилировщика). Важным моментом является то, что вы будете проверять поведение приложения на соответствие вашим ожиданиям, если это имеет смысл. Обнаружение утечек автоматически в окруженной мусором среде по определению близко к невозможному; в противном случае не было бы утечек. Так что имейте это в виду: вы проверяете свои ожидания; Вы тот, кто знает жизненный цикл ваших объектов и может сказать: «В этот момент этот объект должен был быть собран; если нет, то что-то не так».

Теперь, если количество "экземпляров" для вашего представления уменьшается до 0, утечки нет. Если вы считаете, что приложение подтекает, попробуйте найти другие объекты, которые могли быть неправильно утилизированы. Если счет остается на 1, это означает, что ваш взгляд просочился. Теперь вам нужно найти, почему и где.

В этот момент вы должны сделать «снимок памяти» (кнопка рядом с кнопкой «Force GC»). Откройте снимок, найдите объект в сетке и дважды щелкните по нему. Это даст вам список всех объектов, которые имеют ссылку на этот объект. Это на самом деле дерево, и, вероятно, каждый элемент будет содержать в свою очередь множество обратных ссылок и так далее. Это объекты, которые мешают вашему просмотру быть собранным. На правой панели также вы увидите трассировку распределения. Это покажет, как выбранный объект был создан (почти как трассировка стека).

Вы, вероятно, увидите огромное количество объектов там.Но лучше всего сконцентрироваться на тех, кто имеет более длинный жизненный цикл, чем объект, который вы исследуете (на ваш взгляд).Я имею в виду, ищите сцену, родительское представление и т.д .;объекты, от которых зависит ваш взгляд, а не объекты, которые зависят от вашего взгляда, если это имеет смысл.Если в вашем представлении есть кнопка, и вы добавили к ней прослушиватель, у вашей кнопки будет ссылка на ваше представление.В большинстве случаев это не проблема, так как кнопка зависит от вида, и как только вид будет собран, кнопка тоже.Итак, идея заключается в том, что, поскольку объектов много, вы должны стараться оставаться сосредоточенными, иначе вы никуда не добьетесь.Этот метод довольно эвристический, но, по моему опыту, он работает.

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

Надеюсь, это поможет.

2 голосов
/ 10 июня 2010

Flash GC использует комбинацию подсчета ссылок, маркировки и развертки, поэтому он обнаруживает циклические ссылки. Скорее всего, у вас есть другая ссылка в вашем графе объектов. Наиболее распространенная причина заключается в том, что объекты, которые вы хотите удалить, все еще имеют обработчики событий, зарегистрированные на объектах, которые не расположены. Вы можете убедиться, что обработчики всегда зарегистрированы со слабой ссылкой. Вы также можете переопределить addEventListener и removeEventListener во всех (базовых) классах, если это возможно, чтобы посмотреть, какие прослушиватели зарегистрированы и есть ли вероятность, что некоторые из них не будут удалены.

Кроме того, вы можете написать деструкторы для ваших объектов, которые для компонентов пользовательского интерфейса очищают графику и удаляют все дочерние объекты, а для всех объектов удаляют ссылки на все свойства. Таким образом, только ваш объект хранится в оперативной памяти, которая не требует большого объема памяти (небольшая занимаемая площадь 20 B или около того, плюс 4 B на переменную (8 для числа)).

Greetz
back2dos

0 голосов
/ 10 мая 2013

также полезная эвристика для поиска утечек памяти: http://www.tikalk.com/flex/solving-memory-leaks-using-flash-builder-4-profiler

...