Использование памяти во Flash / Flex / AS3 - PullRequest
1 голос
/ 02 июня 2010

У меня проблемы с управлением памятью во флеш-приложении. Использование памяти несколько увеличивается, и я проследил, как я загружаю ресурсы.

Я вставил несколько растровых изображений в класс Embedded, например,

[Embed(source="/home/gabriel/text_hard.jpg")]
public static var ASSET_text_hard_DOT_jpg : Class;

Затем я копирую активы таким образом

var pClass : Class = Embedded[sResource] as Class;
return new pClass() as Bitmap;

В этот момент увеличивается использование памяти, что совершенно нормально. Однако null все ссылки на объект не освобождают память.

Исходя из этого поведения, похоже, что флэш-плеер создает экземпляр класса в первый раз, когда я его запрашиваю, но никогда не выпускает его - не без ссылок, вызывая System.gc (), выполняя двойной трюк LocalConnection, или вызовом dispose () для объектов BitmapData.

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

Мой анализ верен? Можно ли что-нибудь сделать, чтобы это исправить?

Ответы [ 4 ]

1 голос
/ 02 июня 2010

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

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

0 голосов
/ 12 июня 2010

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

Точнее, загрузка SWF, создание множества классов, определенных в нем, добавление их в список отображения, манипулирование ими, а затем удаление всех ссылок и выгрузка SWF оставляет мне почти точно такую ​​же память, с которой я начал. 1003 *

0 голосов
/ 02 июня 2010

На этом этапе использование памяти увеличивается, что совершенно нормально. Тем не мение, обнулить все ссылки на объект не освобождает память.

Это тоже совершенно нормально. В любой системе редко можно гарантировать, что момент, когда вы прекратите ссылаться на объект в коде, будет совпадать с моментом, когда память для него будет возвращена операционной системе. Именно поэтому существуют такие методы, как System.gc (), которые позволяют принудительно выполнять очистку, когда она вам нужна. Обычно приложение может реализовывать своего рода пул для хранения объектов и памяти для повышения эффективности (поскольку распределение памяти обычно медленное). И даже если приложение действительно возвращает память операционной системе, ОС может все же считать ее назначенной приложению на некоторое время, если приложению потребуется запросить еще немного позже.

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

0 голосов
/ 02 июня 2010

Почему вы хотите использовать это ???

var pClass : Class = Embedded[sResource] as Class; 
return new pClass() as Bitmap;

Иногда динамическое назначение ресурсов содержит ошибки и не может быть освобождено. У меня были похожие проблемы с флеш-плеером и flex, например. загрузка и выгрузка одного и того же внешнего SWF-файла ... память постоянно увеличивалась с размером загруженного SWF-файла, не снижаясь, даже если я вызывал system.gc (); после выгрузки SWF.

Поэтому я предлагаю пропустить этот подход и использовать первый описанный вами случай.


ОБНОВЛЕНИЕ 1

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx           = "http://ns.adobe.com/mxml/2009" 
    xmlns:s         = "library://ns.adobe.com/flex/spark" 
    xmlns:mx           = "library://ns.adobe.com/flex/mx" 
    creationComplete   = "creationComplete()">

<fx:Script>
    <![CDATA[



        [Embed(source="/assets/logo1w.png")]
        private static var asset1:Class;

        [Embed(source="/assets/060110sinkhole.jpg")]
        private static var asset2:Class; 


        private static var _dict:Dictionary = new Dictionary();

        private static function initDictionary():void
        {
            _dict["/assets/logo1w.png"] = asset1;
            _dict["/assets/060110sinkhole.jpg"] = asset2;
        }

        public static function getAssetClass(assetPath:String):Class
        {
            // if the asset is already in the dictionary then just return it
            if(_dict[assetPath] !=  null)
            {
                return _dict[assetPath] as Class; 
            }

            return null;
        }

        private function creationComplete():void
        {
            initDictionary();
            var asset1:Class = getAssetClass("/assets/logo1w.png");
            var asset2:Class = getAssetClass("/assets/060110sinkhole.jpg");
            var asset3:Class = getAssetClass("/assets/logo1w.png");
            var asset4:Class = getAssetClass("/assets/060110sinkhole.jpg");
            var asset5:Class = getAssetClass("/assets/logo1w.png");
        }
    ]]>
</fx:Script>

...