Объекты не удаляются без вызова System.gc () - PullRequest
2 голосов
/ 24 января 2012

После некоторых проблем с удалением объектов я запустил простой тест:

  1. Создан простой класс со слабой ссылкой слушатель для Event.ENTER_FRAME.
  2. Добавлен вызов trace("I Exist!") для прослушиваемой функции.
  3. Создание единственного экземпляра с одной ссылкой в ​​классе документа.

Это сработало, как и ожидалось - SWF-файл ничего не делал, кроме печати «Я существую!» каждый кадр на консоль. (В режиме отладки, конечно.)

То, что я сделал дальше, не сработало, как я ожидал:
Я установил единственную ссылку на объект, которая должна быть установлена ​​на null для события мыши, но сообщения от прослушивателя события указанного объекта все еще появлялись в консоли после запуска события мыши, и ссылка была установлена ​​на null - значит объект еще существовал!

Вызов System.gc() в классе документа НЕМЕДЛЕННО остановил прослушиватель событий для печати дальнейших сообщений и, по-видимому, удалил элемент.

Исходя из того, что я понимаю, вызывать System.gc() не рекомендуется, но, как видно из этого простого теста, сборщик мусора - большая НЕУДАЧА.
Я делаю что-то не так, пытаясь избавиться от объекта, или мне просто нужно звонить System.gc() каждый раз, когда я хочу избавиться от объекта ..?

Редактировать: Вызов System.gc() с неслабым слушателем также приводит к удалению объекта из памяти (?)

Ответы [ 4 ]

3 голосов
/ 24 января 2012

Сборка мусора почти всегда откладывается в современных виртуальных машинах (Java, Flash Player, .NET и т. Д.). Вы можете прочитать http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html для получения дополнительной информации.

В частности:

В Flash Player 9 операции сборщика мусора откладываются. Это очень важная вещь для понимания. Ваши объекты не будут удалены сразу после удаления всех активных ссылок. Скорее, они будут удалены в неопределенное время в будущем (с точки зрения разработчика). Сборщик мусора использует набор эвристик, которые, помимо прочего, определяют распределение ОЗУ и размер стека памяти, чтобы определить время запуска. Как разработчик, вы должны принять тот факт, что у вас не будет возможности узнать, когда или даже если ваши неактивные объекты будут освобождены. Вы также должны знать, что неактивные объекты будут продолжать выполняться бесконечно, пока сборщик мусора не освободит их, поэтому ваш код будет продолжать работать (события enterFrame будут продолжаться), звуки будут продолжаться, нагрузки будут происходить, другие события будут запускаться, и так далее.

1 голос
/ 24 января 2012

На самом деле это ожидаемое поведение системы сборки мусора Flash.Процедура сборки мусора выполняется каждый раз, когда вызывается System.gc () или создается новый объект (новое ключевое слово).Вы должны разрешить GC естественную очистку объектов, и в любом случае System.gc () работает только для проигрывателя отладки и ничего не делает для версии выпуска.

Если вы хотите, чтобы слушатель запускался, ВСЕГДА лучше всего вручнуюудалите слушателя самостоятельно с помощью removeEventListener.Однако, если вы не заботитесь о функциональности, существующей до следующего этапа сбора, вы можете просто положиться на слабого слушателя.Надеюсь, это поможет.

0 голосов
/ 24 января 2012

Вы уверены, что удалили все ссылки на свой объект? то есть вы удалили прослушиватель событий мыши, если вы добавили объект на сцену, вы удалили Child?

Как только вы убедитесь, что все ссылки удалены, обнулите объект

object = null;

Тогда важно вызвать System.gc () ДВАЖДЫ

У сборщика мусора есть две фазы: Mark и Sweep. Каждый вызов System.gc () выполняет только одну фазу.

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

http://divillysausages.com/blog/tracking_memory_leaks_in_as3

0 голосов
/ 24 января 2012

Сборка мусора запускается только при выделении во Flash Player , что означает, что установка объекта на null не вызовет сборщик мусора.

Установка объекта на null удаляет только конкретную ссылку на этот объект. Фактически, ваш слушатель все еще имеет ссылку на объект, в вашем случае это слабая ссылка, поэтому, когда GC запускает, объект собирается, но до тех пор он все еще висит в памяти - отправляя и получая любые события, для которых вы его настроили. ручка.

Правильный способ справиться с этим - явно удалить слушателей событий, которые вам больше не нужны, а затем позволить GC делать свое дело, когда все будет хорошо и готово. Обычно я справляюсь с этим, добавляя в свои классы метод destroy(), который позволяет им убирать собственный беспорядок, прежде чем я покончу с ними.

...