Принудительно собирать мусор в AS3? - PullRequest
18 голосов
/ 10 октября 2008

Можно ли программно принудительно запустить полную сборку мусора в ActionScript 3.0?

Допустим, я создал группу объектов Display с помощью EventListeners, и некоторые DO были удалены, некоторые из EventListener были запущены и удалены и т. Д. ... Есть ли способ заставить сборку мусора запускаться и собирать все, что доступно для сбора?

Ответы [ 8 ]

25 голосов
/ 10 октября 2008

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

Во Flash 10 есть метод System.gc(), который вы можете вызвать (но не см. Выше) - имейте в виду, что System.gc () работает только в отладочной версии Flash Player 10+.

Во Flash 9 существует неподдерживаемый способ принудительного использования его через нечетную команду LocalConnection, но он может работать не во всех версиях. Смотрите это сообщение от Гранта Скиннера.

15 голосов
/ 12 июля 2012

Существует новый API для сообщения GC, что это может быть "относительно хороший момент" для сбора.

См. Документы Adobe API для System.pauseForGCIfCollectionImminent

А также это сообщение в блоге Adobe вскоре после того, как метод появился в Player версии 11

Метод принимает аргумент "неизбежность"; в основном, вы вводите небольшое число (около 0,0), если вы действительно хотите, чтобы коллектор работал, даже если с момента последнего сбора не было большой активности (в настоящее время измеряемой байтами), и вы вводите большое количество около 1.0), если вы хотите, чтобы приостановка сбора происходила только в том случае, если мы уже были рядом с точкой, в которой сбор произошел бы в любом случае.

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

Одна очень важная деталь: этот новый API поддерживается как Release, так и Debugger Flash Runtime. Это делает его лучше вызова System.gc ().

8 голосов
/ 10 октября 2008

Для всех выпущенных в настоящее время версий System.gc () работает только в отладочной версии Flash Player и ADL (среда отладки для приложений AIR). Флеш-плеер 10 бета в настоящее время работает во всех вариантах.

Я согласен с Давром, это плохая идея. Время выполнения обычно будет лучше, чем у вас.

Кроме того, особенности работы сборщика мусора - это детали реализации, которые могут изменяться между версиями флеш-плеера. Так что то, что хорошо работает сегодня, не гарантирует, что оно будет хорошо работать в будущем.

3 голосов
/ 19 апреля 2011
try {
    new LocalConnection().connect('foo');
    new LocalConnection().connect('foo');
} catch (e:*){
    trace("Forcing Garbage Collection :"+e.toString());
}
3 голосов
/ 19 февраля 2010

У меня есть комментарий к тем, кто говорит, что вы никогда не должны делать GC вручную. Я привык к ручному управлению памятью в C ++ и предпочитаю sharedptr, а не GC, но в любом случае.

Есть особый случай, когда я не могу найти другое решение, чем GC. Обратите внимание: у меня есть класс DataCache, он работает так, как будто он сохраняет объекты результатов для определенных вызовов методов, которые отправляют обновленные события при обновлении / получении данных. Способ обновления кеша заключается в том, что я просто удаляю из него все результаты и отправляю событие, которое заставляет всех оставшихся слушателей повторно запрашивать свои данные, и слушатели, вышедшие из области видимости, не должны повторно запрашивать, что очищает ненужные результаты. Но, очевидно, если я не смогу заставить всех слушателей, которые все еще болтаются, ждать немедленной очистки GC перед отправкой события «еще раз запросить ваши данные», эти болтающиеся слушатели будут без необходимости снова запрашивать данные. Так как я не могу удалитьEventListener, потому что в AS3 нет деструкторов, я не вижу другого простого решения, кроме как заставить GC убедиться, что слушателей больше нет.

(Правка) Кроме того, я не могу использовать removeEventListener в любом случае для привязки, которая была настроена в mxml, например (используя мой пользовательский класс DataCacher, который обрабатывает remoteobj)

<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />

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

По крайней мере, поэтому я думаю, что я все еще новичок во Flex, поэтому любые мысли будут оценены.

3 голосов
/ 12 октября 2008

Как говорили другие: не пытайтесь собрать GC вручную, есть хаки, но это небезопасно.

Вы должны попробовать переработать объекты, когда сможете - вы сэкономите много памяти.

Это может быть применено, например, к BitmapDatas (очистить и повторно использовать), частицам (удалить из отображения и повторно использовать).

0 голосов
/ 10 ноября 2010

переработка не очень помогает. Я использовал один загрузчик, который неоднократно загружал один и тот же JPG каждые 500 мс. диспетчер задач по-прежнему сообщал о безостановочном увеличении памяти.

проверенное и проверенное решение здесь.

http://simplistika.com/as3-garbage-collection/

0 голосов
/ 18 сентября 2010

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

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

...