Выгрузка ByteArray с помощью ActionScript 3

91

Как принудительно выгрузить ByteArrayиз памяти с помощью ActionScript 3?

Я пробовал следующее:

// First non-working solution
byteArray.length = 0;
byteArray = new ByteArray();

// Second non-working solution
for ( var i:int=0; i < byteArray.length; i++ ) {
    byteArray[i] = null;
}
Ранн Лифшиц
источник

Ответы:

35

Не думаю, что тебе есть о чем беспокоиться. Если System.totalMemoryупадет, можно расслабиться. Вполне может быть, что ОС не восстанавливает только что освобожденную память (в ожидании следующего раза, когда Flash Player запросит больше памяти).

Попробуйте сделать что-нибудь еще, что очень интенсивно использует память, и я уверен, что вы заметите, что память, выделенная для Flash Player, уменьшится и будет использоваться для другого процесса.

Как я понял, управление памятью в современных ОС не интуитивно понятно с точки зрения количества выделенных каждому процессу или даже общего объема.

Когда я использовал свой Mac в течение 5 минут, используется 95% моих 3 ГБ ОЗУ, и он останется таким, он никогда не отключится. Именно так ОС обрабатывает память.

До тех пор, пока в этом нет необходимости, даже завершившимся процессам по-прежнему назначена память (например, это может ускорить их запуск в следующий раз).

Тео
источник
25

(Я не уверен в этом, но ...)

AS3 использует недетерминированную сборку мусора, что означает, что разыменованная память будет освобождаться всякий раз, когда среда выполнения считает нужным (обычно, если нет причины для запуска, поскольку выполнение этой операции является дорогостоящей). Это тот же подход, который используется большинством современных языков сбора мусора (например, C # и Java).

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

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

Чтобы принудительно создать сборщик мусора, попробуйте (да, дважды):

flash.system.System.gc();
flash.system.System.gc();

Вы можете узнать больше здесь .

Карл Сегин
источник
20

Взгляните на эту статью

http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

Программист IANA ActionScript, однако у меня такое ощущение, потому что сборщик мусора может не запускаться, когда вы этого хотите.

Следовательно, http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

Поэтому я бы рекомендовал попробовать их код коллекции и посмотреть, поможет ли это

private var gcCount:int;
private function startGCCycle():void{
    gcCount = 0;
    addEventListener(Event.ENTER_FRAME, doGC);
}
private function doGC(evt:Event):void{
    flash.system.System.gc();
    if(++gcCount > 1){
        removeEventListener(Event.ENTER_FRAME, doGC);
        setTimeout(lastGC, 40);
    }
}
private function lastGC():void{
    flash.system.System.gc();
}
Jax
источник
16

К сожалению, когда дело доходит до управления памятью во Flash / actionscript, вы мало что можете сделать. ActionScript был разработан, чтобы его было легко использовать (поэтому они не хотели, чтобы людям приходилось беспокоиться об управлении памятью)

Ниже приводится обходной путь, вместо создания ByteArrayпеременной попробуйте это.

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

//Then when you are finished delete the variable from byteObject
delete byteObject.byteArray;

Если byteArrayзадано динамическое свойство byteObject, вы можете освободить выделенную для него память.

Redbaron
источник
16

Думаю, вы ответили на свой вопрос.

System.totalMemoryдает вам общий объем "используемой", а не выделенной памяти. Совершенно верно, что ваше приложение может использовать только 20 МБ, но у него есть 5 МБ, которые можно использовать в будущем.

Я не уверен, прольют ли документы Adobe свет на способ управления памятью.

Redbaron
источник
11

Итак, если я загружу, скажем, 20 МБ из MySQL, в диспетчере задач ОЗУ для приложения увеличится примерно на 25 МБ. Затем, когда я закрываю соединение и пытаюсь удалить ByteArray, оперативная память никогда не освобождается. Однако, если я использую System.totalMemory, флэш-плеер показывает, что память освобождается, а это не так.

Выполняет ли флэш-плеер что-то вроде Java и резервирует пространство кучи и не освобождает его до завершения работы приложения?

Что ж, да и нет, как вы, возможно, читали из бесчисленных сообщений в блогах, GC в AVM2 оптимистичен и будет работать своими загадочными способами. Таким образом, он работает немного как Java и пытается зарезервировать место в куче. Однако, если вы дадите ему достаточно времени и начнете выполнять другие операции, которые потребляют значительную часть памяти, это освободит предыдущее пространство. Вы можете увидеть это с помощью профилировщика в ночное время, когда некоторые тесты будут запущены поверх вашего приложения.

Педро
источник
10

Итак, если я загружу, скажем, 20 МБ из MySQL, в диспетчере задач ОЗУ для приложения увеличится примерно на 25 МБ. Затем, когда я закрываю соединение и пытаюсь удалить ByteArray, оперативная память никогда не освобождается. Однако, если я использую System.totalMemory, флэш-плеер показывает, что память освобождается, а это не так.

Плеер «освобождает» память. Если вы минимизируете окно и восстановите его, вы увидите, что мемориальная информация теперь намного ближе к тому, что показывает System.totalMemory.

Вам также может быть интересно использовать инструменты профилирования FlexBuilder, которые могут показать вам, действительно ли у вас есть утечки памяти.


источник