2011-02-10 16 views
11

Wiem, że pytania profilera mogą być dość ogólne, ale tutaj mam bardzo konkretne pytanie i przykład.Flash Builder 4 Profiler: jak wykryć, jakie obiekty powodują wzrost znanej pamięci?

wiem, że w następnym kodem (pobranej z Joshua's question), który jest nieskończona liczba koło przypadkach obiektów są dodawane do hostComponent. To oczywiście powoduje stopniowe spowolnienie aplikacji.

Moje pytanie brzmi: kiedy uruchamiam program Flash Builder Profiler, gdzie dokładnie widzę problem?

Running example of the app

Aby go wypróbować, utwórz nowy Flex 4 projektu i wklej ten kod:

<?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

nie mogę się doczekać odpowiedzi na ten jeden. Odczytałem dane wyjściowe profilera. +1 na dobre pytanie. –

Odpowiedz

10

Po pierwsze, chciałbym spojrzeć na panelu wykorzystania pamięci po graniu trochę z aplikacja:

enter image description here

Wskazówka pamięci wzrasta coraz bardziej. Istnieje przycisk "Run Garbage Collector", który wymusza GC. Jednak po kliknięciu na nią pamięć nie zmniejsza się.

Następnym krokiem jest zidentyfikowanie winnych. W tym celu należy użyć Live panelu obiektów:

enter image description here

Wygląda na to, że niektóre przypadki appart wektor, wszystko wygląda w porządku. Domyślnie wiele klas jest filtrowanych z datagridu obiektów aktywnych. Na szczęście można określić, które klasy będą wyświetlane i ukryte. Wszystkie klasy z pakietów flash.x.x są domyślnie ukryte. Usuwając je z filtrowanej listy przynieść somthing ciekawego do stołu:

enter image description here

Zawiadomienie wiersz graficzna: 871 przypadki zostały stworzone i wszystkie są nadal w pamięci! Dzięki tym informacjom można przypuszczać, że instancje grafiki są odpowiedzialne za spowolnienie działania aplikacji. Jeśli odfiltrujesz również klasy mx. *, Zobaczysz 871 instancji UIComponents. Za każdym razem, gdy tworzony jest UIComponent, istnieje również obiekt graficzny.

Ostatnim krokiem jest usunięcie każdego składnika UIComponent, gdy nie jest już potrzebny na ekranie i sprawdzenie, czy nastąpiła poprawa wydajności.

+1

+1 Usunięcie filtrowania dało znacznie więcej informacji. W opcjach konfiguracyjnych Run Run Profiler zaznacz "Generate Object Alignment Trace". Zrób dwie migawki pamięci, wybierz obie, kliknij znajdź obiekty lojalnościowe. Użyj śledzenia alokacji, aby zobaczyć, kiedy tworzone są komponenty uiComponents (na tykanie zegara) - wskazuje to kierunek we właściwym kierunku. – Ryan

+0

Zostanie opublikowany zrzut ekranu przedstawiający, jak szybko znaleźć właściwego winowajcę. – Ryan

8

Flash Builder Profiler

  1. Uruchom aplikację przy użyciu Profiler (wybierz opcja Generowanie śladu alokacji obiekt pytany)
  2. Weźmy dwa pamięci Migawki af kilka sekund od siebie
  3. Wybierz obie Zdjęcia migawkowe i kliknij Znajdź obiekty do przeskakiwania
  4. Pamiętaj, aby kliknąć opcję Filtruj ering i usuń wszystkie filtry
  5. Sortuj według pamięci. UIComponent znajdzie się na górze/blisko góry listy
  6. Kliknij dwukrotnie UIComponent w oknie Obiekty Loitering - w tym oknie pojawi się okno Referencje obiektu.
  7. Kliknij element UIComponent w obszarze Wystąpienia i wyświetl jego ślad alokacji, dzięki czemu dowiesz się, gdzie został utworzony ten element UIComponent (jeśli klikniesz dwukrotnie widok śledzenia alokacji, w którym zostanie wyświetlony numer wiersza - 30 w tym przypadku - zostanie otwarty ta lokalizacja w widoku Źródło).

Teraz znasz źródła problemu pamięci

Aby rozwiązać ten akumulacyjne wyciek pamięci, należy dodać następujące:

Po fadeEffect.play(); dodać

fadeEffect.addEventListener(EffectEvent.EFFECT_END, onEffectEnd); 

i dodać funkcję:

private function onEffectEnd(event:EffectEvent):void 
{ 
    trace(hostComponent.numChildren); 
    hostComponent.removeChild(event.target.target); 
    event.target.target = null; 
} 
+0

Tak, funkcja porównywania migawek pamięci zazwyczaj bardzo pomaga –

+0

Mogę po prostu dodać (lub coś przeoczyłem) - krok 4 należy wykonać przed krokiem 2, albo zdjęcia będą filtrowane i nie będą zawierały wszystkich obiekty. – Kricket