![]() |
|
||||||||||
|
|||||
|
С тех пор как мы ловили RTE в релизной версии плеера, потому что в дебаговой этого RTE не было — я отношусь к версиям FP очень внимательно.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Если не вызвать принудительно GC, и подождать немножко пока сам запустится, то получим:
loader удаляется если описаны от всех слушателей и e.target.loader.content не находится в списке отображения; e.target.loader.content не находится в списке и без ссылки - тоже удаляется; loader удаляется, если на e.target.loader.content есть ссылка, не находится в списке отображения, обнулен; не удаляется loader, если не отписаться от слушателей; не удаляется loader, если на e.target.loader.content была ссылка за пределами функции, не удаляется loader, если e.target.loader.content находится в списке отображения но нет ссылки за пределами функции, вот так все печально. Последний раз редактировалось VitaliyKrivtsov; 29.01.2011 в 02:18. |
|
|||||
|
Прошу прощения, туплю =)
Цитата:
__________________
Тут мужик танцует и поёт про флэш |
|
|||||||
|
.
|
Всем привет! Пару дней сидел без интернета.
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Вышли мы из функции, ссылка пропала. Цитата:
Дальше расскажу что происходит с loader при загрузке растровых изображений (JPEG, PNG, GIF). Эксперимент проводился с Adobe Flash Player 10.0 r45 debug. Результат исследований заставил задуматься. Пока существует ссылка на BitmapData контента (loader.content as Bitmap).bitmapData, (loaderInfo.content as Bitmap).bitmapData, жив и лоадер. Можно даже сделать ей dispose(), ничего не изменится. Скажу больше. Даже bitmapData.clone() не позволит удалиться лоадеру. Однако после bitmapData.draw() GC может удалить Loader. Код маленького эксперимента /////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011. Dimarik // /////////////////////////////////////////////////////////////////////////////// package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.IEventDispatcher; import flash.net.URLRequest; /** * @author Dimarik * @version 1.0 * @langversion 3.0 * @playerversion 9.0 * */ [SWF(width="400", height="200", frameRate="21", backgroundColor="#E0EEEE")] public class LoaderTest extends Sprite { //------------------------------------------------------------------------- // // Constructor // //------------------------------------------------------------------------- public function LoaderTest() { super(); super.addEventListener(Event.ADDED_TO_STAGE, this.initialize); } //------------------------------------------------------------------------- // // Private methods // //------------------------------------------------------------------------- private var _bitmapData: BitmapData; //------------------------------------------------------------------------- // // Private methods // //------------------------------------------------------------------------- public function initialize(event:Event):void { (event.target as IEventDispatcher).removeEventListener(event.type, arguments.callee); super.stage.scaleMode = StageScaleMode.NO_SCALE; super.stage.align = StageAlign.TOP_LEFT; var url: String = 'http://www.flasher.ru/forum/image.php?u=69797&dateline=1296252938'; var request: URLRequest = new URLRequest(url); var loader: Loader = new Loader(); loader.load(request); var li: LoaderInfo = loader.contentLoaderInfo; li.addEventListener(Event.COMPLETE, this.handler_complete); } //------------------------------------------------------------------------- // // Events handlers // //------------------------------------------------------------------------- /** * @private * В таком виде в методе не произойдет удаление Loader */ private function handler_complete(event:Event):void { var li: LoaderInfo = event.target as LoaderInfo; var loader: Loader = li.loader; trace(li.contentType); // Раскомментируйте, чтобы проверить, что отписывание не влияет на решение GC об удалении loader //li.removeEventListener(Event.COMPLETE, this.handler_complete); var bitmap: Bitmap = loader.content as Bitmap; var bitmapData: BitmapData = bitmap.bitmapData; // Дублирование исходной BitmapData не влияет на лоадер. Он будет жить. var bitmapData2: BitmapData = bitmapData.clone(); // Однако draw не обладает такой силой. // Раскомментируйте, чтобы проверить, что в этом случае лоадер будет удален /* var bitmapData2: BitmapData = new BitmapData(bitmapData.width, bitmapData.height); bitmapData2.draw(bitmap); */ bitmap = new Bitmap(bitmapData2); // Пока есть ссылка на bitmapData, лоадер не будет удален. Закомментируйте для удаления лоадера. this._bitmapData = bitmapData2; // Пока используется оригинальная bitmapData или раздупленная через clone() лоадер будет жить. //super.addChild(bitmap); loader.unloadAndStop(); } } } |
|
|||||
|
Очень интересные выводы.
Могу сказать, что // Раскомментируйте, чтобы проверить, что отписывание не влияет на решение GC об удалении loader //li.removeEventListener(Event.COMPLETE, this.handler_complete); Сейчас не очень много времени проверить вот какой факт: достаточно ли факта draw (даже без захвата пикселей) для удаления из памяти, достаточно ли снятия хотя бы одного пикселя с помощью draw, достаточно ли снятия больше половины пикселей. Практической ценности никакой, но интересно. Если не секрет, как ты догадался проверить удаляется ли после draw? Цитата:
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
VitaliyKrivtsov,
вот этот пункт у меня не работает Цитата:
private function completeHandler(event : Event) : void { var loader : Loader = (event.target as LoaderInfo).loader; var bitmap : Bitmap = loader.content as Bitmap; var sprite : Sprite = new Sprite(); this.contentLink = loader.content; //sprite.addChild(bitmap); //sprite.addEventListener(MouseEvent.CLICK, clickHandler); //addChild(sprite); loader.unloadAndStop(true); } Добавлено через 7 минут Цитата:
Чем меньше слов new (и фабричных методов) в коде тем меньше вероятность утечек=)
__________________
Сам себе репортер |
|
|||||
|
У вас ссылка contentLink в пределах поля класса есть, ее нужно будет удалить из списка отображения а потом занулить, когда bitmap уже будет не нужен, так же желатильно отписать от слушателей loader и занулить его, и тогда - будет удален и лоадер и битмап.
Последний раз редактировалось VitaliyKrivtsov; 03.02.2011 в 20:08. |
|
|||||
|
.
|
В том и дело, что если для каждой картинки создавать свой лоадер, то в памяти будет висеть и растр и лоадер. Однако если грузить картинки и, вообще, ресурсы, через ограниченное число лоадеров (речь идет именно об экземплярах класса Loader), то мы бережем память на getSize(new Loader()) * numКартинок - getSize(new Loader()) * numLoaders; Чем больше картинок, тем большая экономия.
|
|
|||||
|
Чаще всего загвоздка в том, что злые дяди забывают сделать для нас crossdomain.xml, и вытащить content "бережно" для памяти никак. (повторный loadBytes, по-сути, хак, и как правильное решение его рассматривать не стоит)
__________________
Тут мужик танцует и поёт про флэш |
![]() |
![]() |
Часовой пояс GMT +4, время: 02:21. |
|
|
« Предыдущая тема | Следующая тема » |
|
|