Вопрос

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

Нет правильного решения

Другие советы

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

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

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

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

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

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

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

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

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

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

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

Ниже приведен обходной путь вместо создания 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, ОЗУ никогда не освобождается.Однако, если я использую System.totalMemory, флеш-плеер показывает, что память освобождается, но это не так.

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top