Подтвердить что ты не робот

Собирать сбор мусора в AS3?

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

Скажем, я создал кучу объектов Display с eventListeners, и некоторые из DO были удалены, некоторые из eventListeners были запущены и удалены и т.д.... Есть ли способ заставить сбор мусора запускать и собирать все, что доступно для сбора?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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

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

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

Ответ 6

try {
    new LocalConnection().connect('foo');
    new LocalConnection().connect('foo');
} catch (e:*){
    trace("Forcing Garbage Collection :"+e.toString());
}

Ответ 7

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

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

Ответ 8

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

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

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