Удаление объектов. Утечки памяти во Flash.

В данной статье я хотел бы вам рассказать о правильном (на мой взгляд) способе удаления объектов и об утечках памяти во flash.

1. Введение

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

Многие начинающие флэшеры, как и я в свое время, слабо понимают необходимость высвобождения памяти от ненужных объектов и классов. Так вот заранее хочу их предупредить – в более менее сложном проекте где вам придется постоянно работать с динамическими данными\объектами, у вас возникнет необходимость очищения памяти от «отработанных» объектов.

2. Откуда берутся утечки памяти?

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

var classLink : Sprite = new Sprite();

В данном примере мы создаем новый экземпляр класса Sprite и classLink есть ничто иное как ссылка указывающая на данный экземпляр класса.

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

var classLink : Sprite = new Sprite();
var doubleLink : Sprite = classLink;
 
classLink = null;

…то экземпляр класса Sprite не будет удален из памяти. Так же стоит помнить, что если вы используете ссылку на данный объект еще где либо – например вы добавили объект на сцену:

this.addChild(classLink);

..то display list сцены будет содержать ссылку на данный экземпляр класса, и при приравнивании classLink к null не даст вам никаких результатов. Тот же случай ожидает вас при использовании подписки на события объекта (addEventListener);

Мораль: необходимо удалять все ссылки на объект, чтобы сборщик мусора очистил участок памяти занимаемый объектом.

3. От теории к практике. Модель уничтожения.

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

В своих ссылках я упомянул великолепную библиотеку CASALib, она содержит в своем составе RemovableEventDispatcher и различные интерфейсы вроде IRemovable, IDestroyable, и стандартные классы CasaSprite, CasaMovieClip, CasaTextField и т.д. и т.п.; стандартные классы представляют из себя ничего более кроме как самоуничтожающиеся классы которые в своем арсенале имеют такие методы как removeEventListeners (отписывание всех слушателей) и destroy (убирание себя со сцены, отписывание от всех слушателей и уничтожение собственного ListenerManager’a), и кучу еще всего полезного.

А теперь друзья мои вопрос – к чему я все это написал? К тому чтобы вы посмотрели код класса CasaSprite и усвоили раз и навсегда, что пускай не самым удобным, но очень качественным способом уничтожения объектов для вас будет создание для классов деструктора, в котором будут удаляться все зависимые ссылки, с последующим их обнулением.

  classLink.destroy();
  classLink = null;

Я настоятельно рекомендую использование библиотеки CASALib и её модели деструкторов, поверьте мне — это облегчит вам жизнь.

seeAlso: ListenerManager, IRemovable, IDestroyable.
ps. Это не пропаганда, и не заказной пост (для опенсорса смешно звучит кстати), просто данная библиотека (можно смело назвать подручный фрэймворк) существенно облегчит вам жизнь, и сделает программирование приятнее и удобнее.

Тэги:

Вторник, Ноябрь 10, 2009, 02:44
Подписаться на комментарии.
Вы можете оставить комментарий, или trackback со своего сайта.



5 комментариев

  1. можно было бы упомянуть об weakReference.

  2. Владислав

    Спасибо за наводку. В свое время пришлось писать простые подобные классы для sprite и MovieClip, а оказывается все уже придумано =)

  3. Илья Маланьин

    Felicast,
    можно было бы упомянуть об weakReference.

    Ох и вправду! Из головы совсем вылетело. В ближайшее время добавлю.

  4. bicubic_bublic

    а как же быть с doubleLink ?

    var classLink : Sprite = new Sprite();
    var doubleLink : Sprite = classLink;
    classLink.destroy();
    classLink = null;

    имхо сколько не используй удобных либ, все равно надо быть самому на чеку и самому все чекать..

  5. Илья Маланьин

    bicubic_bublic,
    а как же быть с doubleLink ?

    Мораль: необходимо удалять все ссылки на объект, чтобы сборщик мусора очистил участок памяти занимаемый объектом.

Оставить комментарий