|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Сборщик мусора. Удаляется объект, который в дисплей листе.
Привет. Заголовок немного желтоват. На самом деле код выглядит так:
package { import flash.display.Sprite; import flash.events.MouseEvent; public class GCTest extends Sprite { public function GCTest() { stage.addEventListener(MouseEvent.CLICK, stageMouseClickHandler); } private function stageMouseClickHandler(event:MouseEvent):void { var a:A = new A(); addChild(a.vis); } } } import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.system.System; internal class A { public var vis:Sprite = new Sprite(); private const _SHAPE:Shape = new Shape(); function A() { vis.graphics.beginFill(0xFF0000); vis.graphics.drawCircle(0, 0, 50); vis.graphics.endFill(); _SHAPE.addEventListener(Event.ENTER_FRAME, entarFrameHandler); } private function entarFrameHandler(event:Event):void { trace('enter frame handler'); System.gc(); } }
__________________
http://volgogradetzzz.blogspot.ru/ |
|
|||||
Banned
|
Ну так все правильно. После вот этого:
"a.vis" будет живет долго и счастливо, так как он в дисплей листе. А вот "a" умирает, так как на него нет ни одной ссылки. GC удаляет не целостные объекты и не подмножества...а те на которые нет ссылок. |
|
|||||
Но если он его удалит, значит он должен удалить все его поля, в том числе и vis. Т.е. память, занимаемая объектами должна освободиться. Но vis на месте и я могу обращаться к нему. А что если позже что-то перезапишется на эту память?
__________________
http://volgogradetzzz.blogspot.ru/ |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Не путайте ссылку и значение. Ссылка будет удалена, а объект останется, так как на него есть другая ссылка — в контейнере.
Добавлено через 7 минут public var vis:Sprite — это переменная, хранящая ссылку. Это не сам спрайт. Это ссылка, где его искать. new Sprite(); — вот собственно "сам" спрайт, создаваемый где-то в памяти. Где — сохраняется в переменной. Или не сохраняется явно, а только во внутреннем хэше контейнера:
__________________
Reality.getBounds(this); |
|
|||||
Wolsh, не понял. Если срабатывает ГЦ, то он именно удаляет объекты. Вот еще пример.
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.system.System; public class GCTest extends Sprite { public function GCTest() { stage.addEventListener(MouseEvent.CLICK, stageMouseClickHandler); } private function stageMouseClickHandler(event:MouseEvent):void { var a:A = new A(); addChild(a.s); var s:Sprite = new Sprite(); addChild(s); s.addEventListener(Event.ENTER_FRAME, test, false, 0, true); } private function test(event:Event):void { trace('inside main'); System.gc(); } } } import flash.display.Sprite; import flash.events.Event; import flash.system.System; internal class A { public var s:Sprite = new Sprite(); function A() { s.addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true); s.graphics.beginFill(0x00FF00); s.graphics.drawCircle(0, 0, 50); s.graphics.endFill(); } private function enterFrameHandler(event:Event):void { trace('inside A'); System.gc(); } }
__________________
http://volgogradetzzz.blogspot.ru/ |
|
|||||
Цитата:
Объект - это кусок памяти, в котором лежат: - вспомогательная информация - ссылки на другие объекты (физически 4 байта) - примитивные типы (int, Number) - физически 4, 8 байт И вот это всё лежит в линеечку (для одного объекта) Ссылки ссылаются на другие объекты. Т.е. удалить объект - это удалить как раз ссылки на другие и примитивные значения. Объекты и их ссылки представляют собой не _дерево_, а _граф_ Здесь нельзя просто взять и удалить вместе с объектом те, на которые он ссылается. На эти ссылочные объекты может ссылаться кто-то ещё. По поводу примера кода - не смотрел ещё, вообще странно. |
|
|||||
Цитата:
Пример, да, странный. У меня еще парочка необъяснимых имеется.
__________________
http://volgogradetzzz.blogspot.ru/ |
|
|||||
Регистрация: Jan 2009
Сообщений: 1,651
|
Пример не странный, пример реальный. Я впервые столкнулся с таким удалением, когда делал игрушку, которая пачкой loader'ов загружала множество кусочков карты по 100 на 100 пикселей. Так вот я просто создавал в теле функции loader'ы и сразу кидал на сцену, нигде не хранил. И на некоторых компьютерах я увидел, что объекты лоадера ГЦ съедает даже еще до того, как картинка загрузилась. Причем, не очень уже хорошо помню, давно это было, но уверен, что на все загрузчики были навешаны слушатели, и не weak, и все равно ГЦ их съедал. Решил проблему хранением массива этих загрузчиков в классе, пока они все не загрузились.
__________________
мой пустой блог |
|
|||||
Цитата:
А так вы навесили слушатель - т.е. добавили ссылку на себя в лоадер - как это должно помешать его сборке? По порядку: private function stageMouseClickHandler(event:MouseEvent):void { var a:A = new A(); addChild(a.vis); } 2. Вы взяли у экземпляра A vis и добавили его в список отображения 3. Вы нигде не сохранили ссылку на сам экземпляр A (функция отработала - ссылок на экземпляр A не осталось, остался только vis в списке отображения) Что должно получиться: - ничего не мешает собрать GC экземпляр A - GC не может собрать vis. public var vis:Sprite = new Sprite(); private const _SHAPE:Shape = new Shape(); function A() { vis.graphics.beginFill(0xFF0000); vis.graphics.drawRect(-25, -25, 50, 50); vis.graphics.endFill(); _SHAPE.addEventListener(Event.ENTER_FRAME, entarFrameHandler); } 4. _SHAPE на сцену не добавляется 5. на _SHAPE ссылается экземпляр A, на который вы не сохранили никаких ссылок Что должно произойти: - Экземпляр _SHAPE должен быть снесён сборщиком мусора Вывод: Хороший пример, демонстрирующи работу GC и никакой мистики! Последний раз редактировалось expl; 16.01.2013 в 16:19. |
Часовой пояс GMT +4, время: 08:27. |
|
« Предыдущая тема | Следующая тема » |
|
|