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

Как принудительно выгрузить объект 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;
}

Ответов (8)

Используйте эти ресурсы:

http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b8cbfe-7ff7.html

и это

http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b8cbfe-7ff7.html

К сожалению, когда дело доходит до управления памятью во 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, вы можете освободить выделенную для него память.

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

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

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

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

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

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

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

Я считаю, что вы ответили на свой вопрос.

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

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

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

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();
}

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

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

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

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

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

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

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

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

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

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

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