![](http://distilleryimage6.s3.amazonaws.com/14cef07ea6e111e296f222000a9f4dd8_7.jpg)
К примеру, получить массив с теми же элементами, только возведенными в квадрат:
var squared:Array = array.map(function(value:Number):void { return value * value; });
Javascript достаточно проницательно подтягивает в scope closure только используемые ссылки на объекты. Однако ActionScript не столь элегантен, поэтому, если вы решили использовать во flash механизм closure, то в него затянуться все ссылки из окружения, и что еще хуже, эти ссылки повиснут в памяти надолго, возможно и навсегда.
Можно принудительно обнулять локальные переменные, как в примере на строчке 118. Вот пример с обнулением:
Структура
1) В коде у нас есть основной класс - ClosureLeaks и вспомогательный - ClosureLeaksTest с тестовым методом execute в котором спрятан closure;2) Так же есть массив _pool со слабыми ссылками, используется для отслеживания, какие экземпляры еще живы;
3) В ClosureLeaksTest есть статический массив _pool так же со слабыми ссылками, назначение аналогичное;
4) В ClosureLeaks так же есть несколько методов log* логирования объектов из _pool;
Эксперимент
1) Создаем 4 экземпляра ClosureLeaksTest, у троих запускаем еще метод execute(), содержащий closure.2) В closure через некоторый промежуток времени обнуляем один из объектов;
3) Логируем состояние до и после;
Результат
Удаляется экземпляр ClosureLeaksTest, в котором мы не вызывали execute(), а так же локальные переменные, которые мы принудительно обнулили.Но все оказалось еще хуже - в ходе экспериментов выяснилось, что если класс имеет (!) не статический метод с closure, а мы создали экземпляр этого класса, и вызвали метод с closure (в примере это execute) - экземпляр повисает навсегда.
Таким образом, если не хотите засорять память, используйте closure только в статических методах, и обнулите локальные переменные. А лучше не используйте closure вообще т.к. лучшая практика - это придерживаться одной практики.
Спасибо Makc3D, он также провел эксперимент, и получил аналогичный результат - scope не освобождается.
flash on 2013-4-20 - wonderfl build flash online
Update
Оказывается все не так уж плохо, ссылки в closure все таки чистятся, достаточно запустить System.gc(). Либо по убедить FlashPlayer, что памяти недостаточно, но как известно эта фаза поиска неиспользуемых участков памяти более ресурсоемкая, поэтому все же стоит избегать closure в часто запускаемых участках кода, т.к. память выделенная в ходе их исполнения будет еще долго болтаться балластом.Пример closure с System.gc()
Closure Memory Leak with System.gc() - wonderfl build flash online
PS
Фото @bureanka_uaPPS
Приятный, неожиданный побочный эффект статьи - пример кода стал 1№ в тот же день.![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6vgDu1O_9A8XZ3bsGM-ENSBLygcGR2KD1sFMbesoPwHSDYsBLVu2yHWz283WXPGuuHD6fCHBnZ-X3vdnLgjprQYlGFJJRlHMY6CKR3kXOJUAVZX6exJJUwvBOCBGcjNVzrzs_iNTWWBk/s0/2013-04-20_12-07-56.png)
Комментариев нет:
Отправить комментарий