Национальный Аэрокосмический Университет им.Н.Е.Жуковского «ХАИ» Кафедра 503 Утечки памяти, повышение производительности во Flash Автор доклада: Студент группы 555аМ Дмитренко А.Ю. Харьков 2014 Просто о сложном Для начала надо усвоить две важные вещи: Примитивные типы, такие как uint, int, Boolean, String, Number всегда передаются только в качестве значений Сложные типы, такие как Array, XMLList, XML, Date и т.д. передаются всегда в качестве ссылки на объект Что это значит на практике? Результат: Как видите при изменении value1 значение value2 осталось прежним, так как в value2передается именно значение из value1. Другой пример: Результат: На этот раз дело обстоит иначе, если в предыдущем примере значения у нас разнились, то в текущем случае массив value2 “принял” изменения массива value1. Почему так произошло? Array (массив) это сложный тип, и когда мы присваиваем переменной value2 значение value1, то на самом деле мы передаем ссылку на уже существующий массив. То есть в value1 и в value2 находится ссылка на один и тот же объект, который размещен в памяти нашего приложения. Повторим: при создании массива (как и любой другой сущности сложного типа) мы создаем объект в памяти приложения, а в качестве значения переменной получаем ссылку на него. Утечки памяти Причины: 1. После того как объект перестал быть нужным на него сохраняются ссылки явные и неявные, либо объект не деактивируется 2. Чрезмерное создание объектов 3. Повторное создание экземпляра BitmapData вместо повторного использования 4. Отсутствие пула объектов 5. Использование событий там, где это неуместно 6. Векторная и растровая графика 1. После того как объект перестал быть нужным на него сохраняются ссылки явные и неявные, либо объект не деактивируется Почему ссылки на объекты могут сохраняться? Присвоение переменной значения null не гарантируется удаление его из памяти. На это есть несколько причин: К данном объекту привязаны слушатели событий, и перед тем как присваивать ему значение null необходимо отписаться от всех событий, с помощью методаremoveEventListener. Если это экранный объект, то он может находится в дисплей-листе другого экранного объекта. Следовательно его необходимо сначала удалить из дисплей-листа, с помощью метода removeChild Работающие таймеры (класс Timer) всегда остаются в памяти, даже если у них отсутствуют слушатели. Необходимо останавливать таймеры перед удалением, с помощью метода stop. Деактивация объектов Под деактивацией объектов подразумевается все, что было описано в пунктах выше, но помимо этого существуют ещё несколько важных моментов. В случае когда вы работаете с BitmapData, то при её создании резервируется количество байт = ширина * высоту * 4 (width * height * 4), где 4 это количество байт на один пиксель. Например: 0xFFFFFFFF представляет собой белый непрозрачный цвет в формате ARGB, 0xAARRGGBB. Чтобы очистить память используемую BitmapData необходимо сначала использовать метод dispose. После этого можно удалять ссылки на данный объект. Многие разработчики очень любят использовать XML в качестве хранилища данных и конфигурационных структур. Структура XML занимает немалое количество памяти при большом объеме содержащейся в ней информации. Начиная с версии 10.1 Flash Player была добавлена возможность сделать XML доступным для сбора в качестве мусора с помощью статического метода disposeXMLкласса System. 2. Чрезмерное создание объектов 3. Повторное создание экземпляра BitmapData вместо повторного использования Например, у вас есть изображение со снежинкой. Вместо того, чтобы создавать кучу объектов со снежинками, достаточно создать одну BitmapData и использовать её несколько раз. Таким образом у нас будет задействована всего лишь одна BitmapData, но на экране мы увидим 200 одинаковых снежинок. 4. Отсутствие пула объектов Пул представляет собой хранилище уже проинициализированных объектов, которые будут использоваться в рабочем процессе. В случае когда возникает необходимость в объекте, он не будет создаваться, а будет взят из пула, и после использования будет возвращен обратно. Использовать пул необходимо в местах, где часто создаются и удаляются объекты, чтобы не провоцировать процесс сбора мусора. Реализация пула может выглядеть совершенно поразному, это может быть отдельный класс выполняющий роль пула для любых объектов определенного типа, или же типизированныйVector, или просто Array. 5. Использование событий там, где это неуместно Диспетчеризация событий во время цикла Event.ENTER_FRAME. 6. Векторная и растровая графика Профилактика Итоги Отписывайтесь от событий которые больше вам не пригодятся Уничтожайте все неиспользуемые данные Помечайте ссылки на неиспользуемые объекты при помощи null, для того, чтобы сборщик мусора мог их уничтожить Не создавайте множество объектов там, где можно обойтись одним Используйте пулы вместо частого создания и удаления объектов Возьмите за привычку писать деструкторы Пишите понятный код