2011-02-10 7 views
11

Sé que las preguntas de mi perfil pueden ser bastante generales, pero aquí tengo una pregunta y un ejemplo muy específicos.Flash Builder 4 Profiler: cómo detectar qué objetos están causando un aumento de memoria conocido?

sé que en el siguiente código (tomado de Joshua's question), que un número infinito de círculo instancias de objetos se están añadiendo a la hostComponent. Esto obviamente causa una desaceleración gradual de la aplicación.

Mi pregunta es, cuando ejecuto Flash Builder Profiler, ¿dónde exactamente veo dónde está el problema?

Running example of the app

Para probarlo, crear un nuevo proyecto Flex 4, y pegar en el código:

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

no podemos esperar a ver una respuesta a éste. He tenido muy poca suerte descifrando la salida del generador de perfiles. +1 para una buena pregunta. –

Respuesta

10

En primer lugar, me gustaría ver en el panel de uso de la memoria después de jugar un poco con el aplicación:

enter image description here

Aviso la memoria aumenta cada vez más. Hay un botón "Ejecutar el recolector de basura" que fuerza al GC. Sin embargo, cuando hace clic en él, la memoria no disminuye.

El siguiente paso es identificar a los culpables. Para ello, se utiliza el panel Objetos vivo:

enter image description here

Parece que, aparte algunos casos vectorial, todo se ve Allright. De forma predeterminada, muchas clases se filtran de la cuadrícula de datos de objetos en vivo. Afortunadamente, uno puede especificar qué clases se mostrarán y ocultarán. Todas las clases de los paquetes flash.x.x están ocultas por defecto. Retirarlas de la lista filtrada llevar somthing interesante para la tabla:

enter image description here

Aviso la fila Gráficos: 871 casos se han creado y todos ellos están todavía en la memoria! Con esa información, puede suponer que las instancias de Graphics son responsables de la ralentización de la aplicación. Si también filtra las clases mx. *, Verá que hay 871 instancias de UIComponents. Cada vez que se crea un UIComponent, hay un objeto Graphics también instalado.

El paso final es eliminar cada UIComponent una vez que ya no se necesita en la pantalla y ver si hay alguna mejora en el rendimiento.

+1

+1 Eliminar el filtrado dio mucha más información. En las opciones de configuración de Run Profiler, marque 'Generar seguimiento de asignación de objetos'. Tome dos instantáneas de memoria, seleccione ambas, haga clic en buscar objetos vagabundos. Utilice el seguimiento de asignación para ver cuándo se crean los uiComponents (en el tic del temporizador): esto apunta en la dirección correcta. – Ryan

+0

Publicaremos una captura de pantalla de cómo encontrar el culpable exacto en un momento. – Ryan

8

Flash Builder Profiler

  1. Ejecutar la aplicación utilizando Profiler (elegir la opción de Generar rastro de asignación de objetos cuando se le preguntó)
  2. tomar dos instantáneas memoria af pocos segundos de diferencia
  3. seleccionar tanto de la Las instantáneas memeory y haga clic en Búsqueda Merodeo Objetos
  4. Asegúrese de hacer clic Filt y eliminar cualquier filtro
  5. Ordenar por memoria. UIComponent será superior/cerca de la parte superior de la lista
  6. doble UIComponent clic en la ventana de objetos Holgazanear - esto nos lleva a la ventana de referencias a objetos.
  7. Haga clic en un UIComponent en Instancias y vea su Rastreo de asignación, esto le permitirá saber donde se creó ese UIComponent (si hace doble clic en la vista Rastreo de asignación donde le da el número de línea - 30 en este caso - se abre esa ubicación en la vista de Fuente).

Ahora se conoce el origen del problema de memoria

Para solucionar la pérdida de memoria acumulativa, añada lo siguiente:

Después fadeEffect.play(); añadir

fadeEffect.addEventListener(EffectEvent.EFFECT_END, onEffectEnd); 

y añadir la función:

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

Sí, las instantáneas de memoria Comparativa de programas por lo general ayuda mucho –

+0

que sólo podría añadir (o de lo que me he perdido algo) - paso 4 debe hacerse antes del paso 2, o de lo contrario se filtrarán las instantáneas y no contener toda la objetos. – Kricket

Cuestiones relacionadas