Flash Builder 4 Profiler: как определить, какие объекты вызывают увеличение памяти? - PullRequest
11 голосов
/ 10 февраля 2011

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

Я знаю, что в следующем коде (взятом из вопроса Джошуа ), что к hostComponent добавляется бесконечное число экземпляров объекта circle Это, очевидно, вызывает постепенное замедление приложения.

Мой вопрос: когда я запускаю Flash Builder Profiler, где именно я вижу, в чем проблема?

Пример запуска приложения

Чтобы попробовать, создайте новый проект Flex 4 и вставьте следующий код:

<?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" minWidth="955" minHeight="600"
               initialize="onInit()" viewSourceURL="srcview/index.html">
    <fx:Script>
        <![CDATA[
            import mx.core.UIComponent;
            import mx.effects.Fade;         
            import spark.effects.Move;

            private var hostComponent:UIComponent;

            private function onInit():void{

                hostComponent = new UIComponent();
                hostComponent.id = "circleHostComponent";
            }

            /* Add circle UIComponent objects to the hostComponent.
                Move and Fade the circle objects */
            private function onTimerEvent(event:TimerEvent):void{  

                var yPos:Number = Math.ceil(Math.random()*100);
                var radius:Number = Math.ceil(Math.random()*5); //1-12
                var effectAlpha:Number = Math.random()*0.5 + 0.2 // 0-1
                var effectDuration:Number = Math.ceil(Math.random()*3000) + 1000;

                var circle:UIComponent = new UIComponent();
                circle.graphics.beginFill(0x1C75BC, effectAlpha);
                circle.graphics.drawCircle(90, yPos, radius);
                circle.graphics.endFill();

                hostComponent.addChild(circle);

                var moveEffect:Move= new Move(circle);
                moveEffect.xBy = 300;
                moveEffect.duration = effectDuration;

                moveEffect.play(); 

                var fadeEffect:Fade = new Fade(circle);
                fadeEffect.alphaFrom = 1;
                fadeEffect.alphaTo = 0;
                fadeEffect.duration = effectDuration;

                fadeEffect.play();

                this.addElement(hostComponent);

            }

            private function onClick():void{
                startButton.enabled = false;
                var t:Timer = new Timer(100, 0);
                t.start();
                t.addEventListener(TimerEvent.TIMER, onTimerEvent);

            }       

        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <s:Button id="startButton" label="Click to Start" click="onClick()" />
</s:Application>

Ответы [ 2 ]

10 голосов
/ 13 февраля 2011

Сначала я бы посмотрел на панель «Использование памяти», немного поиграв с приложением:

enter image description here

Обратите внимание, что память увеличивается все больше и больше.Есть кнопка «Запустить сборщик мусора», которая вызывает GC.Однако при нажатии на него память не уменьшается.

Следующим шагом является выявление виновных.Для этого вы используете панель «Живые объекты»:

enter image description here

Выглядит так, добавьте несколько экземпляров Vector, все выглядит хорошо.По умолчанию многие классы фильтруются из сетки данных живых объектов.К счастью, можно указать, какие классы будут отображаться и скрываться.Все классы из пакетов flash.xx по умолчанию скрыты.Удаление их из отфильтрованного списка приводит к чему-то интересному для таблицы:

enter image description here

Обратите внимание на строку Графика: создано 871 экземпляр, и все они все еще находятся в памяти!С этой информацией вы можете предположить, что экземпляры Graphics ответственны за замедление работы приложения.Если вы также отфильтруете классы mx. *, Вы увидите, что существует 871 экземпляр UIComponents.Каждый раз, когда создается UIComponent, также создается экземпляр объекта Graphics.

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

8 голосов
/ 14 февраля 2011

Flash Builder Profiler

  1. Запустите приложение с помощью Profiler (выберите опцию Создать трассировку выделения объекта при запросе)
  2. Возьмите два снимка памяти с интервалом в несколько секунд
  3. Выберите оба снимка памяти и нажмите Найти бесполезные объекты
  4. Обязательно нажмите «Фильтрация» и удалите все фильтры
  5. Сортировка по памяти. UIComponent будет сверху / ближе к вершине списка
  6. Дважды щелкните UIComponent в окне «Бесполезные объекты» - откроется окно «Ссылки на объект»
  7. Нажмите UIComponent под Instances и просмотрите его Allocation Trace, это даст вам знать где этот UIComponent был создан (если вы дважды щелкнете по представлению Allocation Trace, где он даст вам номер строки - 30 в данном случае - он откроет это местоположение в представлении Source).

Теперь вы знаете источник проблемы с памятью

Чтобы исправить накопительную утечку памяти, добавьте следующее:

После fadeEffect.play (); добавить

fadeEffect.addEventListener(EffectEvent.EFFECT_END, onEffectEnd);

и добавьте функцию:

private function onEffectEnd(event:EffectEvent):void
{
   trace(hostComponent.numChildren);
   hostComponent.removeChild(event.target.target);
   event.target.target = null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...