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





Да, это возможно, но в целом это плохая идея. GC должен иметь лучшее представление о том, когда лучше запускать, чем вы, и за исключением очень конкретного случая, например, вы только что использовали 500 МБ памяти и вам нужно вернуть его как можно скорее, вам не следует вызывать GC. себя.
Во Flash 10 есть метод System.gc(), который вы можете вызывать (но не делайте этого, см. Выше) - имейте в виду, что System.gc () работает только в отладочной версии Flash player 10+.
Во Flash 9 существует неподдерживаемый способ принудительного включения с помощью нечетной команды LocalConnection, но он может работать не во всех версиях. См. эта почта Гранта Скиннера.
Во Flash 11 есть метод System.pauseForGCIfCollectionImminent(), который вы можете вызвать. Требуется аргумент, чтобы вы могли дать сборщику мусора представление о том, насколько неизбежной должна быть сборка, чтобы возникла пауза. Для получения дополнительных сведений / ссылок см. Мой ответ ниже.
Для всех выпущенных в настоящее время версий System.gc () работает только в отладочной версии проигрывателя Flash и ADL (среда отладки для приложений AIR). Бета-версия Flash Player 10 в настоящее время работает во всех вариантах.
Я согласен с Давром, это плохая идея. Среда выполнения обычно имеет лучшее представление, чем вы.
Кроме того, особенности работы сборщика мусора - это деталь реализации, которая может меняться в зависимости от версии Flash Player. Так что то, что хорошо работает сегодня, не гарантирует, что оно будет хорошо работать в будущем.
Есть конкретный случай, у меня есть класс DataCache, он работает так, что он сохраняет объект результата, который отправляет обновленные события при обновлении / получении данных. Способ очистки кеша заключается в том, что я просто очищаю от него все результаты и отправляю событие, которое заставляет оставшихся слушателей повторно запрашивать свои данные. Если я не могу заставить всех слушателей, которые все еще болтаются, ожидая очистки GC, перед отправкой события обновления, эти висячие слушатели снова запросят данные.
Как говорили другие: не пытайтесь собрать GC вручную, есть хаки, но это небезопасно.
По возможности вы должны попробовать объекты переработка - вы сэкономите много памяти.
Это может быть применено, например, к BitmapDatas (очистка и повторное использование), частицам (удаление из отображения и повторное использование).
У меня есть комментарий к тем, кто говорит, что никогда не следует делать сборку мусора вручную. Я привык к ручному управлению памятью в C++, и я предпочитаю sharedptr мусору, но в любом случае.
Есть конкретный случай, когда я не могу найти другого решения, кроме GC. Обратите внимание: у меня есть класс DataCache, он работает так, чтобы сохранять объекты результатов для определенных вызовов методов, которые отправляют обновленные события при обновлении / получении данных. Способ обновления кеша заключается в том, что я просто очищаю от него все результаты и отправляю событие, которое заставляет всех оставшихся слушателей повторно запрашивать свои данные, а слушатели, вышедшие за пределы области видимости, не должны повторно запрашивать, что очищает ненужные результаты. Но, по-видимому, если я не могу заставить всех слушателей, которые все еще болтаются, ожидая очистки GC, немедленно перед отправкой события «запросить данные снова», эти висячие слушатели будут запрашивать данные снова без необходимости. Так как я не могу удалитьEventListener, потому что AS3 не имеет деструкторов, я не вижу другого простого решения, кроме как заставить сборщик мусора убедиться, что больше нет болтающихся слушателей.
(Edit) Вдобавок ко всему я не могу использовать removeEventListener для привязки, которая была настроена, например, в mxml (используя мой собственный класс DataCacher, который обрабатывает remoteobj)
<mx:DataGrid id = "mygrid" dataProvider = "{DataCacher.instance().result('method').data}" ... />
Когда всплывающее окно, содержащее эту сетку данных, закрывается, можно ожидать, что привязки будут уничтожены. Видно они живут и живут. Хм, не следует гибко уничтожать все привязки (то есть прослушиватели событий) от объекта, когда он является отмечен для GC, потому что последняя ссылка удалена. Это вроде бы решило проблему для меня.
По крайней мере, поэтому я думаю, что я все еще новичок в Flex, поэтому любые мысли будут оценены.
Если нужно, вызов сборщика мусора может быть полезным ... так что вы должны быть осторожны, как и когда вы это делаете, но нет никаких сомнений в том, что бывают случаи, когда это необходимо.
например, если у вас есть приложение, которое является модульным, при переходе от одного представления к другому все удаленные объекты могут представлять большой объем памяти, который должен быть доступен как можно быстрее, вам просто нужно иметь контроль над переменные и ссылки, которые вы удаляете.
переработка на самом деле не помогает. Я использовал один загрузчик, который многократно загружал один и тот же файл jpg каждые 500 мс. диспетчер задач по-прежнему сообщал о непрерывном увеличении памяти.
проверенное и проверенное решение здесь.
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*){
trace("Forcing Garbage Collection :"+e.toString());
}
Можете ли вы объяснить, какова связь с сборщиком мусора и почему это заставляет это делать?
Есть новый API для сообщения GC, что это может быть «относительно хороший момент» для сбора.
См. Документацию по Adobe API для System.pauseForGCIfCollectionImminent
А также этот Сообщение в блоге Adobe вскоре после того, как метод был представлен в версии Player 11.
Метод принимает аргумент «неизбежности»; в основном, вы вводите небольшое количество (около 0,0), если вы действительно хотите, чтобы сборщик запускался, даже если не было большой активности (в настоящее время измеряется выделенными байтами) с момента последней коллекции, и вы загружаете большое количество ( около 1.0), если вы хотите, чтобы приостановка сбора произошла только в том случае, если мы уже были рядом с точкой, где сбор все равно произойдет.
Мотивация здесь для ситуаций, например, в игры, в которых вы хотите немного сместить точку, в которой происходит сбор мусора, например делать сборку мусора во время смены уровня в игре, а не через две секунды после того, как игрок начал исследовать уровень.
Одна очень важная деталь: этот новый API поддерживается как Release, так и Debugger Flash Runtime. Это делает его лучше, чем вызов System.gc ().
Это отличный ответ, но упускается один очень важный момент. В любом случае это работает только в отладочных плеерах! System.gc () - только для версии отладчика Flash Player и приложений AIR. В приложении AIR метод System.gc () включен только в содержимом, запущенном в AIR Debug Launcher (ADL), или, в установленном приложении, в содержимом изолированной программной среды безопасности приложения. [liveocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/sy stem /…