Flash CS3 - как очистить память

У меня вопрос, как очистить / освободить память во флеш-памяти? Например, я заканчиваю игру и хочу начать с начала, и если я просто перейду к первому кадру, все объекты, которые все еще находятся в этой памяти, есть ли возможность принудительно очистить память?

Могу ли я освободить память для объекта? например, я removeChild (что-то) - и я хочу освободить память для объекта, поскольку я буду использовать его повторно?

Кто-нибудь может объяснить мне, как работает двигатель?

Спасибо


person canimbenim    schedule 04.05.2011    source источник


Ответы (3)


Я бы посоветовал вам прочитать главу 14 «Сборка мусора» в «Книге муков» (Essential ActionScript 3.0 от O'Reilly Publishing).

Короткий ответ на ваш вопрос заключается в том, что вы не контролируете выделение памяти, а сборщик мусора. В языках со сборкой мусора, таких как AS3 или Java, у вас нет ручного управления выделением и освобождением памяти, как в языках нижнего уровня; нет эквивалентов AS3 таким вещам, как удалить в C ++ или бесплатно в C. Ваша цель не должна контролировать, когда вы уничтожаете объекты, а скорее не забывать удалять ссылки на вещи, которые вам больше не нужны, и убедитесь, что вы отключили то, что намеревались использовать для сборки мусора.

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

Предыдущий респондент опубликовал это:

myObject = null;

Это удаляет ссылку на объект, который хранится в переменной myObject. Больше ничего. Вам нужно знать намного больше о ситуации, чтобы иметь возможность сказать, делает ли это присвоение даже соответствующий объект подходящим для сборки мусора, особенно сколько других переменных содержат ссылки на объект. И объект может уже иметь право на сборку мусора, даже если вы не установили для ссылки значение null (т.е. если myObject не имеет связи с корнем сборщика мусора).

Достаточно сказать, что весь механизм GC более сложен, чем можно удовлетворительно объяснить в сообщении StackOverflow. Вот почему у него есть целая глава в книге Moock Book, и даже в этой книге нет подробностей реализации или подробностей о том, когда именно Flash Player выполняет подсчет ссылок на удаления или отметки и проходы очистки.

Самое важное, что нужно помнить, ИМХО:

  1. Когда вы намереваетесь «убить» объект, дайте ему функцию cleanUp () или destroy (), в которой вы делаете такие вещи, как остановка всех его таймеров, звуков, удаление слушателей и т. Д. Объект будет продолжать существовать и выполнять код, пока не получит GC'd. А Flash Player откладывает сборщик мусора до тех пор, пока это возможно - обычно он запускается, когда проигрывателю требуется выделить больше оперативной памяти из вашей системы, потому что выделение памяти - это единственное, что требует больше времени, чем выполнение метки и очистки сборщика мусора.

  2. Читайте о слабых и сильных слушателях. По сути, когда у вас слабый слушатель, ссылка на слушателя игнорируется сборщиком мусора с меткой и очисткой, поэтому сама по себе она не помешает сбору объекта. Но не слушайте тех, кто говорит вам «всегда используйте слабые» или «всегда используйте сильные слушатели и вручную удаляйте их», потому что бывают случаи, когда каждый из них подходит, и поэтому выбор за вами.

person Adam Smith    schedule 05.05.2011

removeChild() удалит объект со сцены, но все равно сохранит его в памяти. Вам придется null этот объект myObject = null, если вы хотите полностью от него избавиться. Возможно, вам и не нужно думать об этом. В большинстве случаев достаточно просто удалить его со сцены и удалить все связанные с ним события.

person Michael D    schedule 04.05.2011
comment
хорошо, я понял, но когда я перехожу к кадру 1 из кадра 3 и я нулевой объект в кадре 3, он не начинается с начала, и у меня есть ошибка: не удается получить доступ к свойству или методу ссылки на нулевой объект. поэтому этот метод myObject = null мне не подходит. Я хочу начать весь фильм с самого начала - person canimbenim; 04.05.2011
comment
Возможно, в кадре 1 вам просто нужно проверить, существует ли объект. Если это так, вы можете использовать его повторно, если нет, создайте его ... Похоже, вам не нужно очищать свои объекты. Вам, вероятно, просто нужно сбросить их свойства, когда вы вернетесь к кадру 1 ... - person Michael D; 05.05.2011
comment
Проверка существования объекта перед попыткой пометить его как GC является правильной. Провести небольшое исследование по сборке мусора в AS3 также правильно, так как это очень важная тема. Однако программирование на временной шкале неверно, и его следует избегать любой ценой. - person Bosworth99; 05.05.2011
comment
myObject = null если вы хотите полностью избавиться от этого, это не так, сборка мусора немного сложнее - person Daniel; 05.05.2011

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

Чтобы объект был готов к сбору данных, он не может иметь связи с другим объектом.

поэтому, если у вас есть объект, который имеет одно соединение с MovieClip, а фрагмент ролика не имеет другого отношения, то, если вы установите для него значение null, вы удалите его.

Однако если у вас есть два объекта, которые указывают на него, если вы удалите одну ссылку, установив для нее значение null, MovieClip не будет удален.

Более того, если у вас есть 2 или более фрагментов ролика с сетью подключений, удаление этих объектов также требует разрыва этих подключений. Например, если у вас настроен уровень с множеством персонажей и слушателей, удаление lavel movieClip не очистит его.

один из способов разорвать эти соединения - добавить события onRemovedFromStage, которые удаляют дополнительных дочерних элементов, слушателей и объекты. Я начал использовать расширение Movieclip casaLib - CasaMovieClip, в котором есть функция removeChildrenAndDestroy. это немного упрощает задачу, но для реализации в более старом проекте потребуется время.

Как бы то ни было, вы обнаружите, что существует множество сайтов, обсуждающих это, лучше всего начать с блог гранта скиннера

person Daniel    schedule 05.05.2011