Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как очистить память при работе с массивом MovieClip'ов? (http://www.flasher.ru/forum/showthread.php?t=140685)

ignition 05.06.2010 11:58

Как очистить память при работе с массивом MovieClip'ов?
 
Как очистить память при работе с массивом MovieClip'ов? Что нужно сделать, чтобы при подгрузке очередного MovieClip'а предыдущий выгружался из памяти? Сейчас, пока я не переберу все элементы массива, отжирается память. Хотелось бы ее освобождать как-то.
А сама схема такая: есть спрайт на слое под кнопками, я в этот спрайт с помощью addChild и removeChild подсовываю MovieClip'ы из массива (нажатии кнопок nextVideo и prevVideo).

КорДум 05.06.2010 13:26

Пока живы ссылки на объекты - они не будут подмяты GC. Поэтому нужно обnullить элементы массива.

ignition 05.06.2010 13:40

КорДум
Как так "обnullить"... :) Мне нужно подгрузить из массива MovieClip, проиграть его, сменить на другой MovieClip из массива, очистить память. Ну и т.д. Мне не нужно убивать массив. Мне не нравится что массив полностью в памяти висит, а не только тот MovieClip, что проигрывается в данный момент времени. Например, я запускаю первый элемент массива, в этот момент времени в памяти только он, и ему не нужны остальные элементы. Зачем мне при проигрывании второго элемента удерживать в памяти первый? Наверняка его можно как-то выгрузить...

Добавлено через 9 минут
[add]
И второй вопрос - почему при загрузке MovieClip'а памяти отжирается в десятки раз больше чем он весит? Видео из MovieClip'а весит 7 метров, а при подгрузке MovieClip'а отжирается около 200 метров. Если бы отжиралось 7 метров, я бы про память не спрашивал ;)

КорДум 05.06.2010 13:50

Обnullить вот так: arr[5] = null. Тогда ссылка на мувиклип пропадет, клип будет доступен сборке мусора. В вашей ситуации, когда нужно постоянно менять клипы и они не одноразовые, лучше каждый раз создавать новый экземпляр класса Mc1, Mc2, ..., McN, перед этим удалять все ссылки на клип предыдущий. Это как я бы сделал.
А, или сделать вот так:
Код AS3:

private var arr:Array = new Array(Mc1, Mc2, ..., McN);

Это лишь ссылки на классы клипов. А создавать объекты так:
Код AS3:

var mc1:MovieClip = new arr[0]; // создастся Mc1
removeChild(mc1);
mc1 = null;


ignition 07.06.2010 01:10

Так и не придумал, где (точнее как...) мне в такой схеме прикрутить null:
Код AS3:

var counter:int=-1;
var forward:Array=new Array(clip1_mc,clip2_mc,clip3_mc,clip4_mc,clip5_mc,clip6_mc);
stop();
.....
function goNext(event:MouseEvent) {
        if (video_container_mc.numChildren) {
                video_container_mc.removeChildAt(0);
                //Где-то здесь должен быть null
                <что-то>=null;
        };
        counter=(counter+1)%6;
        var cur_movie:MovieClip=new forward[counter];
        video_container_mc.addChild(cur_movie);
};
.....
next_btn.addEventListener(MouseEvent.CLICK, goNext);

Что должно быть вместо <что-то>?

КорДум 07.06.2010 01:43

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

ignition 07.06.2010 01:47

КорДум
Судя по тому, что мне показывает ProcessExplorer, память не возвращается, так и остается занятой. Пока я не переберу все клипы память отжирается. Как только я иду на второй круг, память больше не занимается.
А почему переменная-ссылка на объект должна обнулиться? Здесь?:
Код AS3:

var cur_movie:MovieClip=new forward[counter];


КорДум 07.06.2010 01:50

Сейчас я воспроизведу ситуацию и гляну через профайлер.

gloomyBrain 07.06.2010 01:55

Цитата:

почему переменная-ссылка на объект должна обнулиться? Здесь?:
Потому что к локальной переменной доступ прекращается в момент выхода из участка кода, где она упоминается. То есть если Вы объявляете переменную в теле функции, то только в этой функции эта переменная будет существовать. А раз так, значит по этой ссылке никак не получить доступ к мувиклипу. Значит про переменную можно забыть.
Если на мувиклип более нет никаких ссылок - значит к нему никак не обратиться - забываем про мувиклип.

ЗЫ
Если Вы смотрите через диспетчер задач - не верьте ему =)

КорДум 07.06.2010 01:58

В общем ясно. Объекты лежат в "корзине" и ждут, когда сборщик мусора решит, что эту корзину следует почистить. Грубо говоря, эти клипы не занимают много памяти, чтобы привлечь внимание сборщика мусора. Где-то здесь была тема про его работу.

ignition 07.06.2010 02:00

gloomyBrain
Если обнуляется переменная (а эта переменная по идее экземпляр объекта), то почему тогда MovieClip остается видимым? У меня в последнем фрейме MovieClip'a stop(); стоит. Видео останавливается и никуда не девается...

КорДум 07.06.2010 02:01

Одно дело сам объект, другое - ссылка на него. Вот та переменная - ссылка.

ignition 07.06.2010 02:01

КорДум: "эти клипы не занимают много памяти"

Каждый клип отжирает около 200 метров памяти. Я бы не сказал, что это "немного"...
Про память я уже здесь спросил:
http://www.flasher.ru/forum/showthread.php?t=140741

КорДум 07.06.2010 02:03

Ну нифига себе! Может вам попробовать вручную запускать ГЦ через класс Silin'а? http://www.silin.su/#AS3/utils/gc
По коду ясно видно, что никаких ссылок на клипы не остается, а значит ГЦ обязан сработать. Тем более при таком объеме отжираемой памяти.

ignition 07.06.2010 02:05

Дык... Я вообще не втыкаю, как так. По ссылке из предыдущей мессаги подробнее.

КорДум 07.06.2010 02:06

А что подробнее? Качаем класс, подключаем, в нужный момент, то есть после удаления клипа, вызываем метод из класса.

ignition 07.06.2010 02:08

Не, я про свою мессагу. Про эту ссылку:
http://www.flasher.ru/forum/showthread.php?t=140741
:)

КорДум 07.06.2010 02:13

А, не увидел.

ignition 07.06.2010 02:25

Все же, что остается висеть под спрайтом...? :) Я создаю экземпляр, выделяю память, подсовываю его под спрайт. Почему этот самый экземпляр виден, если ссылка на него при выходе из процедуры дохнет. Я так понимаю, что при addChild ссылка на мой экземпляр передается спрайту. Вот он эту ссылку и удерживает. Получается, что нужно сделать removeChild и обнулить ссылку. Вот только как это сделать? Я про обнуление в своем примере кода.

КорДум 07.06.2010 10:58

gloomyBrain и я правы, верьте нам. Ссылка отмирает сразу же, нет ее.

ignition 07.06.2010 11:11

КорДум
А ссылка на один экземпляр только одна может быть? Отмирает перменная cur_movie, которая определена в функции, и отмирает ссылка вместе с ней. А какое отношение имеет спрайт к функции? Он же как был до выполнения функции, так и остался после. По идее спрайт, это как переменная, описаная вне функции. Точнее объект, в котором есть переменная (динамический массив или еще что-то типа того) для хранения ссылок на child'ов.
Я, кстати, вообще запутался как выделяется память в AS3... Почему, например, память выделяется не сразу под весь MovieClip, а во время его проигрывания, и для каждого кадра отдельно... Т.е. Я проигрываю MovieClip с последовательностью из 1000 jpeg'ов, так вот память отжирается все это время. В смысле, с каждым кадром свободной памяти становится все меньше.

КорДум 07.06.2010 11:45

Я не могу найти статью в инете, так что дам номер страницы в книге Мука "ActionScript 3.0 Подробное руководство". То, что вас так интересует, описано на странице 537. Там и про ссылки, и про обнуление, и про память.
Про вторую часть вашего поста ничего сказать не могу - я не сведущ в этом.

Добавлено через 12 минут
[IMG]http://s003.***********/i203/1006/96/457626f1719ft.jpg[/IMG]

ignition 07.06.2010 12:07

Спасибо. Прочитал.
И что здесь расходится с тем, что я написал? Ссылок на один объект, если верить тексту, может быть несколько. Одна из них (cur_movie) отмирает. А в video_container_mc ссылка есть. Или в объекте parent нет ссылки на child?

КорДум 07.06.2010 12:11

Как только срабатывает метод removeChild(), ссылка-индекс автоматически удаляется из списка отображения контейнера. Там в конце написано, что после удаления клип может продолжать проигрываться. Также могут срабатывать оставшиеся события. У вас есть такое?

ignition 07.06.2010 12:19

Может продолжать проигрыватся. Я же писал, что в последнем фрейме MovieClip'ов у меня stop() стоит.

КорДум 07.06.2010 12:25

Я иссяк. Остается надеяться на ответы гуру.

ignition 08.06.2010 00:09

Ок. Есть предложение отвлечься от теории... ;) и решить одну проблему - как мне получить доступ к ссылке в моей схеме? В момент, когда я делаю:
Код AS3:

video_container_mc.removeChildAt(0);

имени объекта (точнее имени экземпляра) уже нет, обратиться к нему по имени уже не получится. Нужно как-то выходить на ссылку через video_container_mc. Как это делается?

gloomyBrain 08.06.2010 00:50

Цитата:

Нужно как-то выходить на ссылку через video_container_mc. Как это делается?
Код AS3:

var mc:MovieClip = video_container_mc.getChildAt(глубина) as MovieClip;

По поводу умирания ссылок и тд - если объект находится в дисплей-листе (то есть добавлен на сцену), то мы можем к нему обратиться - только что написал как это можно сделать. А раз к нему можно обратиться, то из памяти он никуда не денется.

ignition 08.06.2010 01:00

gloomyBrain
Т.е. так? :
Код AS3:

var counter:int=-1;
var forward:Array=new Array(clip1_mc,clip2_mc,clip3_mc,clip4_mc,clip5_mc,clip6_mc);
stop();
.....
function goNext(event:MouseEvent) {
        if (video_container_mc.numChildren) {
                var mc_for_kill:MovieClip = video_container_mc.getChildAt(0) as MovieClip;
                video_container_mc.removeChildAt(0);
                mc_for_kill=null;
        };
        counter=(counter+1)%6;
        var cur_movie:MovieClip=new forward[counter];
        video_container_mc.addChild(cur_movie);
};
.....
next_btn.addEventListener(MouseEvent.CLICK, goNext);

Добавлено через 6 минут
Проверил. Обратиться можем, ошибок не вылезает... т.е. можно сделать вывод, что память не освободилась. Так?
Кстати, а в AS3 есть какие-то средства контроля памяти? Есть какая-то ф-ция выводящая инфу?
По идее, если бы не было ссылки, то уже здесь:
Код AS3:

video_container_mc.removeChildAt(0);

вылезла бы ошибка

PS Изменение кода ни как не повлияло на проблемы с памятью. Она все равно забита.

gloomyBrain 08.06.2010 01:37

Цитата:

Проверил. Обратиться можем, ошибок не вылезает... т.е. можно сделать вывод, что память не освободилась. Так?
Да, именно так


Цитата:

Есть какая-то ф-ция выводящая инфу?
System.totalMemory

Цитата:

вылезла бы ошибка
Откуда быть ошибке?
К объекту можно обратиться как через clip1_mc, так и через getChildAt(0) - это ссылки на один и тот же объект.
Объект станет доступным для "поедания" gc только после выполнения
Код AS3:

clip1_mc = null;
removeChildAt(0);

ЗЫ
кстати, после removeChildAt(0) пустых глубин не остается, то есть все объекты в контейнере "упадут" на одну позицию. Теперь на нулевом индексе будет сидеть объект, который раньше был на 1-м

ignition 08.06.2010 01:41

Я до и после:
Код AS3:

video_container_mc.removeChildAt(0);

делаю:
Код AS3:

trace(video_container_mc.numChildren);

Выводится:
1
0


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

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