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

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

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

Регистрация: Jan 2013
Сообщений: 550
Записей в блоге: 1
Советую обратить внимание так же на эту статью
В ней товарищ объясняет, что если удалить ссылку на большой "островок" - участок кода, где много перекрестных ссылок, слушателей и прочего, то GC будет думать, что этот "островок" важен и не удалит его. Поэтому если у вас, допустим, из корня идет одна ссылка на игровой уровень, то при завершении уровня и удалении этой ссылки (и если этот уровень в общей сложности занимает довольно много места), GC не удалит его из памяти.

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

Старый 13.11.2013, 17:10
a7s1h1 вне форума Посмотреть профиль Отправить личное сообщение для a7s1h1 Найти все сообщения от a7s1h1
  № 2  
Ответить с цитированием
a7s1h1

Регистрация: Oct 2013
Сообщений: 126
Странно. А у меня, если убрать из ClassName функцию удаления детей (та, что через while), то при удалении ClassName из Main (Main - это родитель ClassName) объект child не удаляется. В следующий раз при создании ClassName у него уже 2 ребёнка. Наверное, всё-таки, где-то остаются какие-то связи, мешающие удалению ClassName сборщиком.
Почитав ответы и порывшись в интернете, я пришёл к выводу (поправьте, если это не так), что лучший способ чистки - это вручную удалять всё при удалении объекта со сцены. Поэтому проверка помещения на сцену не обязательна, можно исходные данные писать в конструкторе, а для удаления объекта и слушателей можно сделать метод destroy(), отзывающийся на REMOVED_FROM_STAGE, в котором поочерёдно
1 - удаляем всех детей (removeChild)
2 - обнуляем все переменные, ссылавшиеся на объекты
3 - убираем всех слушателей
Таким образом, когда объект "прародитель" удаляет всех своих детей, то каждый из этих детей перед тем, как удалиться со сцены, выполняет эти три пункта и т.д. по цепочке.

- Адекватен ли такой подход? (если не брать в расчёт то, что прийдётся вручную забивать в damage() обнуление всех переменных, ссылающихся на объекты)

- В каких случаях обязательно вместо обычного конструктора использовать махинации с init-cleanup через события добавление-удаление со сцены?

- В каких случаях целесообразно при создании объекта использовать ADDED вместо ADDED_TO_STAGE и, соответственно, REMOVED вместо REMOVED_FROM_STAGE?

Добавлено через 2 минуты
Цитата:
Сообщение от KumoKairo Посмотреть сообщение
Советую обратить внимание так же на эту статью
Не поверите, только что её как раз прочитал) Спасибо.
Возможно, у меня как раз такая проблема. А может, и нет. В любом случае, очень хотелось бы услышать мнение знатоков относительно ручного метода, как описал чуть выше.

Старый 13.11.2013, 17:36
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 3  
Ответить с цитированием
Akopalipsis
Banned

Регистрация: Mar 2013
Сообщений: 1,864
У меня вопрос по теме - обьект обьявлен на уровне класса, затем я в методе создаю обьект и в его конструктор передаю тот обьект, с которого начал вопрос. Следом я помещаю обьект созданный локально в массив и через некоторое время удаляю его. Удалится ли он?

Добавлено через 2 минуты
Был бы очень рад, если бы кто нибудь ответил. С профайлером у меня почему то обьекты живут своей жизнью, а скаут не как не поставлю, у меня виндовс х86, а как я прочёл, нужен х64.

Старый 13.11.2013, 17:39
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 4  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Цитата:
Таким образом, когда объект "прародитель" удаляет всех своих детей, то каждый из этих детей перед тем, как удалиться со сцены, выполняет эти три пункта и т.д. по цепочке.
Не нужно этого всего. Зачем? Вы нагородили лишнего кода и сами себя запутали. Придумали себе проблему на пустом месте.
Удалите всё и напишите нормально, создайте ребёнка в конструкторе и добавте в себя. 1 подписка на enterFrame, и всё! Там кода на пару строк и с памятью всё хорошо будет.

Зачем родителю париться о своих детях, если его с ними и так полностью удалили? Вы тратите лишнее время цп, загромождаете код и только создаёте потенциальные возможности для утечек, не решая при этом никакой проблемы! Ладно, если бы это был какой-то сложный компонент, но у вас то обычные DisplayObject.

KumoKairo,
Ни разу не сталкивался с такой проблемой. Всегда причина всех утечек, больших и маленьких - были по собственной вине.
Автор упомянутой статьи большой уверенности не вселяет. Если утечка и возможна по вине флеш плеера, её как правило, как и любой баг - можно локализовать. Или определить приблизительные условия для её воспроизведения. Фраза "У меня в большом объёме кода где-то возникают утечки" - говорит только о не компетентности самого автора, уж простите.

Akopalipsis,
Объект - он и в африке объект. Это просто "область" данных, которая размещена в памяти программы. А ссылаться на эту область, или на объект, можно и из класса и из экземпляра любого класса и ещё откуда-нибудь. Пока есть ссылка на эту область, не важно откуда, объект - продолжает жить.

пс. Уточню, ссылка в данном случае - возможность внешнего кода "достучаться" до объекта. На объект может ссылаться 100500 других объектов, но если ни один из них не доступен внешне - все отправляются в утиль. Исключением для этого правила являются запущенные таймеры, о которых я писал выше и может быть, ещё какие нибудь редкие внутренние классы флешового апи, о которых сразу предупреждается в справке.
Такая философия.
__________________
Дети не должны знать о своих родителях


Последний раз редактировалось Tails; 13.11.2013 в 18:11.
Старый 13.11.2013, 18:18
КорДум вне форума Посмотреть профиль Отправить личное сообщение для КорДум Найти все сообщения от КорДум
  № 5  
Ответить с цитированием
КорДум
 
Аватар для КорДум

блогер
Регистрация: Jan 2008
Адрес: syktyvkar
Сообщений: 3,803
Записей в блоге: 10
К слову, вызвать GC в релиз-плеере тоже можно. Для этого нужно воспользоваться
Цитата:
какие нибудь редкие внутренние классы флешового апи, о которых сразу предупреждается в справке
созданием битмапдаты с последующим вызовом метода dispose() у нее. Но сразу предостерегу тех, кто обрадуется и пойдет юзать сей костыль. Так делать можно, но только в особо крайних случаях, когда ну вообще никакие оптимизации не помогают. Частый вызов GC тоже существенно тормозит приложение.
__________________
тут я

Старый 13.11.2013, 18:19
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 6  
Ответить с цитированием
Akopalipsis
Banned

Регистрация: Mar 2013
Сообщений: 1,864
Tails Спасибо! я немного запутался, по этому уточню - вот так обьект контайнер удалится?
Код AS3:
package
{
	import flash.display.Sprite;
	import flash.events.Event;
 
	public class Main extends Sprite 
	{
		private var _object:Object;
		private var _storage:Array;
 
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			_storage = new Array();
			_object = new Object();
			_storage.push(new Container(_object));
			_storage.shift();
		}
 
	}
 
}
Код AS3:
package 
{
	public class Container extends Object 
	{
		private var _object:Object;
 
		public function Container(object:Object) 
		{
			_object = object;
		}
 
	}
 
}

Старый 13.11.2013, 18:20
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 7  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
КорДум,
Да верно, для некоторых конкретных типов данных есть такая возможность. Ещё xml объекты можно диспозить. Но в целом - доступ к gc закрыт.

Akopalipsis,
Да.

Это объявление переменной для экземпляров класса.
Код AS3:
private var _object:Object;
Это объявление переменной для самого класса. В этом варианте, контейнер не удалился бы. Подумайте почему.
Код AS3:
private static var _object:Object;
__________________
Дети не должны знать о своих родителях

Старый 13.11.2013, 18:27
КорДум вне форума Посмотреть профиль Отправить личное сообщение для КорДум Найти все сообщения от КорДум
  № 8  
Ответить с цитированием
КорДум
 
Аватар для КорДум

блогер
Регистрация: Jan 2008
Адрес: syktyvkar
Сообщений: 3,803
Записей в блоге: 10
Tails, Михалик вроде как год назад писал, что у XML проблема с диспозом частенька: не удаляется он. Вообще да, можно вызывать GC и так, но как бы не напороться на утечку памяти.
__________________
тут я

Старый 13.11.2013, 18:34
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 9  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
КорДум,
В справке написано, что xml становиться доступным для сборки. Ещё вроде Мук писал, что gc не сразу удаляет объекты, и что у него есть некая система меток. Вызовом диспоза xml - мы лишь "отмечаем" объект для удаления, тем самым облегчая работу сборщику, а не делая её за него.

Вообще, тема конечно интересная, я использую xml и их удаление, пока не замечал утечек. Надо-бы поискать эту статью.
__________________
Дети не должны знать о своих родителях

Старый 13.11.2013, 18:40
a7s1h1 вне форума Посмотреть профиль Отправить личное сообщение для a7s1h1 Найти все сообщения от a7s1h1
  № 10  
Ответить с цитированием
a7s1h1

Регистрация: Oct 2013
Сообщений: 126
Цитата:
Сообщение от Tails Посмотреть сообщение
Придумали себе проблему на пустом месте. Удалите всё и напишите нормально, создайте ребёнка в конструкторе и добавте в себя. 1 подписка на enterFrame, и всё! Там кода на пару строк и с памятью всё хорошо будет.
Наверное, я просто делаю неверные выводы из получаемой информации.
Спасибо за помощь, пожалуй, так и сделаю. Единственное, что я так и не понял - как лучше удалять объекты в случаях, когда мы не удаляем конкретный объект целенаправленно, а в случае удаления родителя. Ведь даже если дети удаляются автоматически с родителем, то ведь слушатели детей всё равно надо удалять отдельно, или нет?

В любом случае, надо, видимо, попробовать написать всё заново, или хотя бы тщательно проверить. Но теперь обойдусь конструктором, без всяких added_to_stage и init, и каждому объекту пропишу метод destroy() с удалением слушателей и обнулением ссылок - на GC больше надежды нет, вручную вернее будет.

Создать новую тему Ответ Часовой пояс GMT +4, время: 10:50.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра
Комбинированный вид Комбинированный вид

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

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


 


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


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