![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|
|
|||||
|
Советую обратить внимание так же на эту статью
В ней товарищ объясняет, что если удалить ссылку на большой "островок" - участок кода, где много перекрестных ссылок, слушателей и прочего, то GC будет думать, что этот "островок" важен и не удалит его. Поэтому если у вас, допустим, из корня идет одна ссылка на игровой уровень, то при завершении уровня и удалении этой ссылки (и если этот уровень в общей сложности занимает довольно много места), GC не удалит его из памяти. Конечно, есть вероятность того, что сам автор статьи что-то начудил со ссылками и не удалил неявные, или не отписался от каких-либо событий, и именно поэтому возникает такая двусмысленность. Но к сведению принять все же надо - желательно удалять ссылку не только на какой-то "автономный" кусок программы, но и отписываться от событий и удалять ссылки внутри этого участка программы. |
|
|||||
|
Регистрация: 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 минуты Цитата:
Возможно, у меня как раз такая проблема. А может, и нет. В любом случае, очень хотелось бы услышать мнение знатоков относительно ручного метода, как описал чуть выше. |
|
|||||
|
Banned
Регистрация: Mar 2013
Сообщений: 1,864
|
У меня вопрос по теме - обьект обьявлен на уровне класса, затем я в методе создаю обьект и в его конструктор передаю тот обьект, с которого начал вопрос. Следом я помещаю обьект созданный локально в массив и через некоторое время удаляю его. Удалится ли он?
Добавлено через 2 минуты Был бы очень рад, если бы кто нибудь ответил. С профайлером у меня почему то обьекты живут своей жизнью, а скаут не как не поставлю, у меня виндовс х86, а как я прочёл, нужен х64. |
|
|||||
|
Цитата:
Удалите всё и напишите нормально, создайте ребёнка в конструкторе и добавте в себя. 1 подписка на enterFrame, и всё! Там кода на пару строк и с памятью всё хорошо будет. Зачем родителю париться о своих детях, если его с ними и так полностью удалили? Вы тратите лишнее время цп, загромождаете код и только создаёте потенциальные возможности для утечек, не решая при этом никакой проблемы! Ладно, если бы это был какой-то сложный компонент, но у вас то обычные DisplayObject. KumoKairo, Ни разу не сталкивался с такой проблемой. Всегда причина всех утечек, больших и маленьких - были по собственной вине. Автор упомянутой статьи большой уверенности не вселяет. Если утечка и возможна по вине флеш плеера, её как правило, как и любой баг - можно локализовать. Или определить приблизительные условия для её воспроизведения. Фраза "У меня в большом объёме кода где-то возникают утечки" - говорит только о не компетентности самого автора, уж простите. Akopalipsis, Объект - он и в африке объект. Это просто "область" данных, которая размещена в памяти программы. А ссылаться на эту область, или на объект, можно и из класса и из экземпляра любого класса и ещё откуда-нибудь. Пока есть ссылка на эту область, не важно откуда, объект - продолжает жить. пс. Уточню, ссылка в данном случае - возможность внешнего кода "достучаться" до объекта. На объект может ссылаться 100500 других объектов, но если ни один из них не доступен внешне - все отправляются в утиль. Исключением для этого правила являются запущенные таймеры, о которых я писал выше и может быть, ещё какие нибудь редкие внутренние классы флешового апи, о которых сразу предупреждается в справке. Такая философия.
__________________
Дети не должны знать о своих родителях Последний раз редактировалось Tails; 13.11.2013 в 18:11. |
|
|||||
|
К слову, вызвать GC в релиз-плеере тоже можно. Для этого нужно воспользоваться
Цитата:
__________________
тут я |
|
|||||
|
Banned
Регистрация: Mar 2013
Сообщений: 1,864
|
Tails Спасибо! я немного запутался, по этому уточню - вот так обьект контайнер удалится?
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(); } } } |
|
|||||
|
КорДум,
Да верно, для некоторых конкретных типов данных есть такая возможность. Ещё xml объекты можно диспозить. Но в целом - доступ к gc закрыт. Akopalipsis, Да. Это объявление переменной для экземпляров класса. Это объявление переменной для самого класса. В этом варианте, контейнер не удалился бы. Подумайте почему.
__________________
Дети не должны знать о своих родителях |
|
|||||
|
КорДум,
В справке написано, что xml становиться доступным для сборки. Ещё вроде Мук писал, что gc не сразу удаляет объекты, и что у него есть некая система меток. Вызовом диспоза xml - мы лишь "отмечаем" объект для удаления, тем самым облегчая работу сборщику, а не делая её за него. Вообще, тема конечно интересная, я использую xml и их удаление, пока не замечал утечек. Надо-бы поискать эту статью.
__________________
Дети не должны знать о своих родителях |
|
|||||
|
Регистрация: Oct 2013
Сообщений: 126
|
Цитата:
Спасибо за помощь, пожалуй, так и сделаю. Единственное, что я так и не понял - как лучше удалять объекты в случаях, когда мы не удаляем конкретный объект целенаправленно, а в случае удаления родителя. Ведь даже если дети удаляются автоматически с родителем, то ведь слушатели детей всё равно надо удалять отдельно, или нет? В любом случае, надо, видимо, попробовать написать всё заново, или хотя бы тщательно проверить. Но теперь обойдусь конструктором, без всяких added_to_stage и init, и каждому объекту пропишу метод destroy() с удалением слушателей и обнулением ссылок - на GC больше надежды нет, вручную вернее будет. |
![]() |
![]() |
Часовой пояс GMT +4, время: 10:50. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|