Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 27.01.2011, 06:04
VitaliyKrivtsov вне форума Посмотреть профиль Отправить личное сообщение для VitaliyKrivtsov Посетить домашнюю страницу VitaliyKrivtsov Найти все сообщения от VitaliyKrivtsov
  № 1  
Ответить с цитированием
VitaliyKrivtsov
 
Аватар для VitaliyKrivtsov

блогер
Регистрация: Apr 2010
Сообщений: 99
Записей в блоге: 5
Отправить сообщение для VitaliyKrivtsov с помощью ICQ Отправить сообщение для VitaliyKrivtsov с помощью Skype™
Attention Вопрос по Garbage Collector

задался вот таким вопросом: "Если в приложение загружается изображение или мувик (не важно, что именно ) и после загрузки нужно удалить loader, то как правильно (если так можно выразится) удалить этот loader, что бы он не завис в памяти с концами". Почитал не много немало литературы по этой теме, в частности заглянул в книгу Мука, вообщем написано везде, что нужно удалить все ссылки на объект а потом обнулить, но как быть в случае, когда нужно, например, загрузить картинку а после удалить loader, но при этом у нас есть ссылка на битмап, удаляем все слушатели , обнуляем loader , выводи в трейс и получаем null, то есть то к чему стремились, но мне не до конца понятно, удалится из памяти сборщиком мусора loader или нет ? И, наверное, из-за того, что есть ссылка на одно из его свойств, а точнее на свойство contentLoaderInfo.
Вот кусок кода в пример:
Код AS3:
private function  loadImage (  ):void {
    var loader:Loader = new Loader( );
    loader.load( new URLRequest("1.jpg") );
    loader.contentLoaderInfo.addEventListener( Event.INIT, initHandler ); 
}
 
private function initHandler( e:Event ):void
{
    var loader:Loader = Loader( e.target.loader );
    var byteArray:ByteArray = ByteArray( e.target.bytes );// а вот и ссылка )
    var bitmap:Bitmap = Bitmap( loader.content );// а вот еще одна ссылка )	// 
    loader.contentLoaderInfo.removeEventListener( Event.INIT, initHandler );
    loader = null;// равно теперь null 	
}
То есть у нас две ссылки на свойство объекта, не на сам объект конечно. Но если все-таки объект удаляется, то удаляются и все значения свойств объекта, значит из памяти должны очистится Bitmap и ByteArray, но это не может произойти из-за, что есть на них ссылки, и свою очередь, ничего на самом деле так и не удалилось. Если я что-то не так сказал о процессе сборки мусора, исправьте пожалуйста.


Последний раз редактировалось VitaliyKrivtsov; 27.01.2011 в 06:07.
Старый 27.01.2011, 06:49
olexandr вне форума Посмотреть профиль Отправить личное сообщение для olexandr Посетить домашнюю страницу olexandr Найти все сообщения от olexandr
  № 2  
Ответить с цитированием
olexandr
 
Аватар для olexandr

Регистрация: Aug 2007
Адрес: Ukraine, Kyiv
Сообщений: 643
Отправить сообщение для olexandr с помощью ICQ Отправить сообщение для olexandr с помощью MSN Отправить сообщение для olexandr с помощью Skype™
По идее лоадер должен удалиться при следующем вызове GC.
Грубо говоря, этот пример работает по тому же принципу:
Код AS3:
var arr:Array = [0,1,2];
var a:int = arr[0];
arr = null;
Вы некоторые данные сохранили по другим ссылкам, а объект и его свойства удаляются.
__________________
сайт, vk

Старый 27.01.2011, 11:38
dimarik вне форума Посмотреть профиль Отправить личное сообщение для dimarik Найти все сообщения от dimarik
  № 3  
Ответить с цитированием
dimarik
.
 
Аватар для dimarik

модератор форума
Регистрация: Sep 2003
Адрес: Москва
Сообщений: 4,630
Записей в блоге: 20
Попытаюсь порассуждать.
Лоадер никуда не денется и GC не может его удалить. Bitmap, как DisplayObject, имеет ссылку на LoaderInfo, который содержит ссылку на Loader.
Код AS3:
trace(e.target.loader == e.target.loader.content.loaderInfo.loader); // true
Если загружать свф, то у всех его визуальных объектов будет ссылка на loaderInfo и, соответственно, loader.
Т.о. пока существует хоть один визуальный объект, загруженный через данный Loader, экземпляр этого лоадера не будет уничтожен.

Добавлено через 18 минут
Не. Даже не так )

Пока существует ссылка на ApplicationDomain, в который лоадер загрузил классы, то будет существовать и сам лоадер. О, как! Кстати, так как картинка является экземпляром Bitmap класса без имени, то "выдернуть" ее класс непосредственно из ApplicationDomain и сделать еще один экземпляр не представляется возможным. Но это можно сделать через ссылку на конструктор BitmapData.

В своих экспериментах с байткодом я загружал картинку, оборачивал ее бинарные данные в именованный класс и, вуаля! Имеем картинку, которую можно в любой момент инстанцировать по ApplicationDomain#getDefinition().

Добавлено через 1 час 22 минуты
Если будет существовать корневой объект (ссылка DisplayObject#root указывает на него), то можно получить ссылки на loaderInfo и его loader. Для загруженных через Loader изображений корневым объектом является сам Bitmap. Опять же это говорит в пользу того, что loader не уничтожается.
__________________
Воспитан в TimeZero. Работаю в Mail.ru.


Последний раз редактировалось dimarik; 27.01.2011 в 11:58.
Старый 27.01.2011, 13:11
cleptoman вне форума Посмотреть профиль Отправить личное сообщение для cleptoman Найти все сообщения от cleptoman
  № 4  
Ответить с цитированием
cleptoman
 
Аватар для cleptoman

блогер
Регистрация: Mar 2007
Сообщений: 1,291
Записей в блоге: 5
Отправить сообщение для cleptoman с помощью ICQ
не лоадер, а Кощей бессмертный получается. т.е. чтобы убить лоадер нужно сделать тройное сальто.
__________________
http://cleptoman.free-lance.ru
achivements: дважды благословлен на воровство. осеяный благодатью

Старый 28.01.2011, 22:09
VitaliyKrivtsov вне форума Посмотреть профиль Отправить личное сообщение для VitaliyKrivtsov Посетить домашнюю страницу VitaliyKrivtsov Найти все сообщения от VitaliyKrivtsov
  № 5  
Ответить с цитированием
VitaliyKrivtsov
 
Аватар для VitaliyKrivtsov

блогер
Регистрация: Apr 2010
Сообщений: 99
Записей в блоге: 5
Отправить сообщение для VitaliyKrivtsov с помощью ICQ Отправить сообщение для VitaliyKrivtsov с помощью Skype™
olexandr, то есть, если ссылка на другой объект через свойство первого объекта сохраняется в другом объекте - первый будет удален из памяти.
Тогда в случае с loader, сам loader мог бы быть удален, а значение bitmap и byteArray сохранилось бы.
Вернусь к Вашему примеру, а именно в второй строчке
Код AS3:
var arr:Array = [0,1,2];
var a:int = arr[0];
значение присваивается, но это не ссылка на arr[0], если я не ошибаюсь, arr должен удалится,
а вот если это ссылка на одно из свойств объекта, то ссылка ведет на тот участок памяти в котором и есть наш объект по ссылке, и при следующем обращении к bitmap мы обращаемся напрямую к объекту типа данных Bitmap минуя loader и его свойство loaderInfo, и это значит, что loader может быть удален со своими свойствами сохраняя при этом bitmap, но тогда зачем такое удаление объекта, если все что с ним связано не удаляется полностью. Тогда вообще не понятно, что удаляется. Или удаляется, то что не было сохранено прежде по ссылке через loader, а все остальное прежде в памяти будет сидеть.
Пожалуйста, уважаемые форумчане, укажите путь праведный. Я уже сам запутался и в одиночку не разберусь.
olexandr, вот еще, если сделать вот так:
Код AS3:
 var oneArray:Array = new Array("a", "b", "c");
 var twoArray:Array = oneArray;// ссылка на oneArray
 oneArray = null;            
 trace(twoArray); // Output: a, b, c, но мы же удалили oneArray, а значения  twoArray выводятся так как  
 // будто ничего и не происходило, oneArray хоть и был занулен, но так и не удалился поскольку ссылка на // него есть
Что в таком случае делать вообще не знаю, массив не удалится из памяти.
dimarik,
это тот не приятный случай когда первый объект ссылается на второй, а второй на первый, при котором даже зануление не поможет.


Последний раз редактировалось VitaliyKrivtsov; 28.01.2011 в 22:11.
Старый 28.01.2011, 23:02
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 6  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Toronto
Сообщений: 6,599
Записей в блоге: 17
Очень интересная тема.
dimarik, я гружу все Bitmap`ы в текущий ApplicationDomain, т.к. коллапса идентификаторов по getDefinition никак не произойдёт. Но
Цитата:
Пока существует ссылка на ApplicationDomain, в который лоадер загрузил классы, то будет существовать и сам лоадер.
То есть мои Loader`ы не удаляются?
Это очень грустная новость. Что можешь посоветовать для загрузки "мимолетных" картинок, которые могут легко появится на экране и так же легко исчезнуть? Создавать каждый раз для картинки дочерний ApplicationDomain мне кажется совсем не хорошей идеей. Для групп картинок "на сеанс", вроде зашли в комнату - увидели лица людей, вышли, "убили" домен - как-то идея тоже чем-то не нравится.

Старый 28.01.2011, 23:45
mayakwd вне форума Посмотреть профиль Отправить личное сообщение для mayakwd Посетить домашнюю страницу mayakwd Найти все сообщения от mayakwd
  № 7  
Ответить с цитированием
mayakwd
 
Аватар для mayakwd

Регистрация: Jul 2008
Адрес: t:2, x: 0.76
Сообщений: 553
Отправить сообщение для mayakwd с помощью ICQ Отправить сообщение для mayakwd с помощью Skype™
Пользуйтесь пожалуйста профайлером, все вопросы отпадут.

Наглядный тест:

Код AS3:
package {
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.utils.Dictionary;
 
	public class LoaderTest extends Sprite {
 
		protected var dict : Dictionary = new Dictionary(true); 
 
		public function LoaderTest() {
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
 
			var loader : Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
			loader.load(new URLRequest("http://www.flasher.ru/forum/image.php?u=21620&dateline=1288193880"));
 
			dict[loader] = true;
		}
 
		private function enterFrameHandler(event : Event) : void {
			var b : Boolean = true;
			for (var prop : * in dict) {
				trace(prop);
				b = false;
			}
			if (b) {
				trace("deleted");
			}
		}
 
		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();
 
			sprite.addChild(bitmap);
			sprite.addEventListener(MouseEvent.CLICK, clickHandler);
 
			addChild(sprite);
 
			loader.unloadAndStop(true);
		}
 
		private function clickHandler(event : MouseEvent) : void {
			var spr : Sprite = event.target as Sprite;
			spr.removeEventListener(MouseEvent.CLICK, clickHandler);
 
			while (spr.numChildren) {
				spr.removeChildAt(0);
			}
 
			removeChild(spr);
		}
	}
}
С использованием new LoaderContext(false,ApplicationDomain.currentDomain) ничего не меняется, так что с ApplicationDomain промашка, или я не до конца понял мысль dimarik'а.
Смотреть тест надо в профайлере с веселой кнопочкой "run gc"
__________________
Блог, Twitter
Брюзга.


Последний раз редактировалось mayakwd; 29.01.2011 в 00:06.
Старый 29.01.2011, 00:03
saikspaik вне форума Посмотреть профиль Отправить личное сообщение для saikspaik Найти все сообщения от saikspaik
  № 8  
Ответить с цитированием
saikspaik

Регистрация: Nov 2009
Сообщений: 300
mayakwd опередил )
Профайлер избавит тебя от неизвестности, так как в нем можно не ждать пока GC решит освободить память, а запустить его принудительно и посмотреть на результат.
Профайлер есть во Flex и FlashDevelop, это из тех что я знаю.

Старый 29.01.2011, 00:26
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 9  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Toronto
Сообщений: 6,599
Записей в блоге: 17
Спасибо всем, теперь я узнал что такое профайлер.
А на самом деле замечание такое сказал весьма авторитетный человек и я уверен что слова его ну пустые.
Флеш плееров много, в одной из проблема может иметь место. Остается дождаться комментариев.

Но за то что вы провели тесты и сказали что в какой-то фп всё ок — спасибо )

Старый 29.01.2011, 00:30
mayakwd вне форума Посмотреть профиль Отправить личное сообщение для mayakwd Посетить домашнюю страницу mayakwd Найти все сообщения от mayakwd
  № 10  
Ответить с цитированием
mayakwd
 
Аватар для mayakwd

Регистрация: Jul 2008
Адрес: t:2, x: 0.76
Сообщений: 553
Отправить сообщение для mayakwd с помощью ICQ Отправить сообщение для mayakwd с помощью Skype™
адекватно работает в любом плеере начиная с 9ой версии, не скажу с какой именно так как проблем в принципе в этом вопросе не возникало.
вообще никто не ставил под сомнения слова димарика, но тесты показывают иную версию происходящего. а ставить авторитет выше адекватных данных попахивает предрассудками.
__________________
Блог, Twitter
Брюзга.


Последний раз редактировалось mayakwd; 29.01.2011 в 00:45.
Создать новую тему Ответ Часовой пояс GMT +4, время: 02:25.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 02:25.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.