![]() |
Сборщик мусора. Удаляется объект, который в дисплей листе.
Привет. Заголовок немного желтоват. На самом деле код выглядит так:
Код AS3:
|
Ну так все правильно. После вот этого:
Код AS3:
|
Но если он его удалит, значит он должен удалить все его поля, в том числе и vis. Т.е. память, занимаемая объектами должна освободиться. Но vis на месте и я могу обращаться к нему. А что если позже что-то перезапишется на эту память?
|
Не путайте ссылку и значение. Ссылка будет удалена, а объект останется, так как на него есть другая ссылка — в контейнере.
Добавлено через 7 минут Код AS3:
new Sprite(); — вот собственно "сам" спрайт, создаваемый где-то в памяти. Где — сохраняется в переменной. Или не сохраняется явно, а только во внутреннем хэше контейнера: Код AS3:
|
Wolsh, не понял. Если срабатывает ГЦ, то он именно удаляет объекты. Вот еще пример.
Код AS3:
|
Цитата:
Объект - это кусок памяти, в котором лежат: - вспомогательная информация - ссылки на другие объекты (физически 4 байта) - примитивные типы (int, Number) - физически 4, 8 байт И вот это всё лежит в линеечку (для одного объекта) Ссылки ссылаются на другие объекты. Т.е. удалить объект - это удалить как раз ссылки на другие и примитивные значения. Объекты и их ссылки представляют собой не _дерево_, а _граф_ Здесь нельзя просто взять и удалить вместе с объектом те, на которые он ссылается. На эти ссылочные объекты может ссылаться кто-то ещё. По поводу примера кода - не смотрел ещё, вообще странно. |
Цитата:
Пример, да, странный. У меня еще парочка необъяснимых имеется. |
Пример не странный, пример реальный. Я впервые столкнулся с таким удалением, когда делал игрушку, которая пачкой loader'ов загружала множество кусочков карты по 100 на 100 пикселей. Так вот я просто создавал в теле функции loader'ы и сразу кидал на сцену, нигде не хранил. И на некоторых компьютерах я увидел, что объекты лоадера ГЦ съедает даже еще до того, как картинка загрузилась. Причем, не очень уже хорошо помню, давно это было, но уверен, что на все загрузчики были навешаны слушатели, и не weak, и все равно ГЦ их съедал. Решил проблему хранением массива этих загрузчиков в классе, пока они все не загрузились.
|
Цитата:
А так вы навесили слушатель - т.е. добавили ссылку на себя в лоадер - как это должно помешать его сборке? По порядку: Код AS3:
2. Вы взяли у экземпляра A vis и добавили его в список отображения 3. Вы нигде не сохранили ссылку на сам экземпляр A (функция отработала - ссылок на экземпляр A не осталось, остался только vis в списке отображения) Что должно получиться: - ничего не мешает собрать GC экземпляр A - GC не может собрать vis. Код AS3:
4. _SHAPE на сцену не добавляется 5. на _SHAPE ссылается экземпляр A, на который вы не сохранили никаких ссылок Что должно произойти: - Экземпляр _SHAPE должен быть снесён сборщиком мусора Вывод: Хороший пример, демонстрирующи работу GC и никакой мистики! |
Да, хороший пример, в мемориз однозначно.
|
Да, с первым понятно, спасибо. Повторю - я не знал, что ГЦ убивает объект, но трогает его поля.
Но как быть со вторым примером (пост 5). |
Там то же самое. Ссылка на A гибнет в конструкторе Main. Для A#s листенер объявлен со слабой ссылкой, которая является последней зацепкой за GC Root. Финал понятен.
Добавлено через 1 минуту "s" как раз будет жить, гибнет A. |
Гибнет А и получается, что хэндлер вместе с ним. Такое возможно? Ведь на хэндлер ссылается A#s. И пускай ссылка слабая, сам же A#s то живой.
|
A#s живой, верно. Но на A есть только одна ссылка через метод enterFrameHandler. Он добавлен во внутренний список хендлеров объекта Sprite (s). Хендлер добавлен слабой ссылкой. Это значит, что если нет ни одной твердой ссылки на объект A, ссылка на него через enterFrameHandler не препятствует сборщику удалить этот самый A.
|
Цитата:
|
Так а почему бы ему не убиться, если он weak?
|
Ну так он же в дисплей листе ). Блин запутанно как то все...
|
Цитата:
|
Так вроде как метод - это Function - обычный объект, наследник Object. Убился А, хозяин s, но сам то s жив, потому что на него ссылка в дисплей листе. Но ведь и на enterFrameHandler есть ссылка из s, в конце концов s и enterFrameHandler связаны... И раз уж enterFrameHandler - это обычный объект, то он то почему должен убиваться?
|
Чтобы объект убился необходимо чтобы не осталось на него ни одной ссылки. Еще раз...
Объект удаляется, если на него, на него, на него нет ссылок. Считайте ссылки на объект A: 1. В конструкторе создается локальная ссылка. При выходе из него она умирает. 2. У s есть на него мягкая ссылка через enterFrameHandler. Она не играет роли при подсчете ссылок на объект. Все. Коллектор удалит этот объект. Вы извините меня, но я уже не знаю как проще рассказать. |
Цитата:
1. У s есть ссылка не на A, а на enterFrameHandler. A и enterFrameHandler - это разные объекты. Да, enterFrameHandler является приватным методом A, но тем не менее, это разные объекты, правильно я понимаю? 2. Вы утверждаете, что при удалении А, удалится и его метод enterFrameHandler (хоть он и связан с s), так? 3. Но s не удалится при удалении A, потому что он в дисплей листе, правильно? |
A = enterFrameHandler в данном случае. Поэтому у s есть слабая ссылка на A.
|
Если это действительно так, то все становится на свои места. Хотя это специфическая инфа, которую я не встречал. Спасибо.
|
"A" ссылается на enterFrameHandler. enterFrameHandler ссылается на "A". Но на enterFrameHandler не ссылается никто из имеющих GC Root. Приходим к тому, что на "А" нет ссылок. "A" молча уходит со своими методами.
|
Вас опять не понятно. Вот эта строчка
Код AS3:
P.S.: не подумайте, что я тролль. Мне нужно докопаться до истины и сложить паззл у себя в голове. |
Цитата:
a.addEventListener("typeOfEvent", b.handler) -теперь a ссылается на метод b -b _не_ ссылается на a -эта связь помешает удалению b из памяти, когда на b не останется других ссылок -эта связь никак не помешает удалению a из памяти Если с мягкими ссылками - то "a ссылается на метод b" перестаёт учитыватся GC вот и всё. GC удаляет объект, когда на него не осталось внешних ссылок (ссылок из дисплей-листа, ссылок из статических полей классов, и т.д.) Ссылки от объектов, которые сами подлежат удалению GC не считаются. Что такое Объекты, которые подлежат удалению? - это объекты на которые нет ссылок объектов, _не_ подлежащих удалению. "Чтобы понять рекурсию надо понять рекурсию" :) |
Stage (GCRoot) --> внутренний список детей --> [object Sprite] --> внутренний список хендлеров -x-> (enterFrameHandler --> [object A])
--> — обычная ссылка. -x-> — мягкая ссылка. |
Цитата:
|
Все ясно. Всем спасибо.
|
| Часовой пояс GMT +4, время: 18:24. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.