PDA

Просмотр полной версии : как работает сборщик мусора?


chabapok
04.03.2010, 17:06
Что-то я не пойму - как работает сборщик мусора. То есть глобально все ясно - если на переменную никто не ссылается - она помечается на удаление.
Но...

1. Предположим, у нас MovieClip, в который addChild()-ом добавили Sprite. У этого sprite свойство parent ссылается на этот MovieClip, значит такой мувик никогда не будет удален?

2. Если сделали var r = BitmapData(), попользовались им (как промежуточным битмэпом, то есть так что он больше не используется), и дальше приравняли r=null, не вызвав r.dispose() -- увидет ли сборщик мусора данные, которые содержались в битмэпе?

3.если на мувике нарисовали что-то через graphics.gradientFill() используя BitmapData, а потом мувиком попользовались и выбросили. для битмэпа dispose ведь не вызывался? значит получается что ссылаясь друг на друга такая конструкция никогда не загарбажится?

4. Практика показывает, что конструкции вроде myvar.addEventListener("tralala", myfunc, false, 0, true ) иногда "ломаются" и внезапно перестают работать. При этом сам обьект myvar вроде как есть, он не локальная переменная и null ему никто не присваивал. Это глюки gc или тут другая причина?

mikhailk
04.03.2010, 23:20
сорри за оффтоп, поскольку не совсем по теме, но GC с моей точки зрения всегда включается невовремя )))

Psycho Tiger
04.03.2010, 23:28
GC собирает мусор по 2 критериями - первый, если не осталось ссылок на объект и второй - забыл какой, но как раз таки как вы в пункте 1 описали, так что...
1) Удалит, если занулили все ссылки на этот мувиклип (включая удаление из дисплей листа)
2) Да, удалит - но когда это будет неизвестно, поэтому лучше сделать dispose()
3) Аналогично с пунктом 1 - выбросится когда нибудь.
4) Что есть ломаются?

mayakwd
04.03.2010, 23:39
Все это можно легко проверить на практике с помощью профайлера.

1. "возможно" будет удален, СМ не обладает высоким интеллектом, в данном случае лучше всего уничтожать вручную.
2. то же самое что в первом пункте.
3. никто ни на кого не ссылается.
4. "weak reference" использовать я лично вообще не рекомендовал бы, так как gc их съедает если они ему по вкусу.

Вся соль в удалении\не удалении - в рекурсивном подходе гс, вы сбросили ссылку на мувиклип например в котором содержался еще один мувиклип, который вы не удалили, таким образом при первой итерации сборщик его не уничтожит, лишь пометит как к возможный к удалению при условии что у для входящих в его состав клипов не существует иных ссылок.

Вообще работа с памятью во флэше очень замороченная, и как оказалось на практике желательно еще и все string'и сбрастывать в null в случае если нет в них больше необходимости. Как например у вас есть какой-нибудь класс наследованный от абстрактного AbstractData

public class InfoData extends AbstractData {
public var userName : String;
public var userId : String;

public function InfoData() {
super();
}
}

никаких иных свойств (включая наследованных) у класса нет а абстрактный "не наследуется ни от чего". так вот при удалении экземпляра класса InfoData, т.е.

var test : InfoData = new InfoData();
test.userName = "Vasya Pupkin";
test.userId = "12312afe99e30";

test = null;

"Возможно" из памяти он и удалится но строки останутся жить, до никому неведомой по счету итерации gc (проверено на практике). Собственно работа с памятью повторюсь крайне уныла (я говорю про 9ый плеер, в десятом я не проверял).

Добавлено через 3 минуты
вся эта возня с занулением уничтожением и т.д. приводит к избыточности кода, от которого к сожалению никуда не скроешься...

chabapok
05.03.2010, 14:02
Ээ, а где взять профайлер? Из флекса? А если у меня флеш-проект?



3. Ну, я проводил эксперимент. Создаем Sprite, делаем в нем градиентную заливку, используя в качаесте градиента BitmapData. После этого делаем битмэпдате dispose(). И градиентная заливка в спрайте - тоже уничтожается. Это наводит на мысль, что внутренее представление графики (Sprite.graphics) когда делаешь заливку, ссылается каким-то образом на соответствующее BitmapData.

mayakwd
05.03.2010, 14:05
СМ - сборщик мусора.
Профайлер да во Флекс Билдере например, в ФДТ тоже появился но пока что не совсем хорошо работает.