Выгрузка 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;
}

9 ответов

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

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

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

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

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

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

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

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

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

Чтобы заставить GC, попробуйте (да, дважды):

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

Вы можете прочитать больше здесь.

Посмотрите на эту статью

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

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

Отсюда 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 дает общий объем используемой памяти, а не выделенной. Это верно, что ваше приложение может использовать только 20 МБ, но оно имеет 5 МБ, что бесплатно для будущих распределений.

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

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

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

Проигрывает ли Flash Player что-то вроде Java, резервирует место в куче и не освобождает его до тех пор, пока приложение не закроется?

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

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

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

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

Использоватьbytearray.clear()

Согласно справочнику по языку

этот

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

Другие вопросы по тегам