Выгрузка ByteArray с использованием Actionscript 3 - PullRequest
82 голосов
/ 01 августа 2008

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

33 голосов
/ 14 августа 2008

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

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

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

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

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

23 голосов
/ 01 августа 2008

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

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

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

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

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

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

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

18 голосов
/ 01 августа 2008

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

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();
}
14 голосов
/ 01 августа 2008

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

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

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

14 голосов
/ 01 августа 2008

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

10 голосов
/ 17 сентября 2008

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

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

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

9 голосов
/ 06 октября 2008

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

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

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

7 голосов
...