2010-04-09 19 views
9

¿Alguien puede publicar un ejemplo de código as3 (específicamente el detector de eventos incluido) que sería un ejemplo simple de algo que podría perder memoria ... también podría publicarse una solución al problema que se muestra?AS3 Memory Leak Example

La pregunta es: ¿Qué es un ejemplo simple de pérdida de memoria en un receptor de eventos AS3 y cómo se puede resolver?

+0

¿Es esta una pregunta de tarea o algo? – davr

+1

No, pero lo planteé como si fuera un jaja ... La idea es tener un buen ejemplo "goto" cuando piense en pérdidas de memoria en general. Un buen 'antipatrón', por así decirlo. – Skawful

Respuesta

7
public class MySprite extends Sprite { 

    public function MySprite() { 
     if(stage) { 
      init(); 
     } else { 
      addEventListener(Event.ADDED_TO_STAGE,init); 
     } 
    } 

    private function init(e:Event = null):void { 
     stage.addEventListener(Event.RESIZE,handleStageResize); 
    } 

    private function handleStageResize(e:Event):void { 
     // do some processing here. 
    } 

} 

En otro lugar:

var mySprite:MySprite = new MySprite(); 
someHolder.addChild(mySprite); 

Ahora bien, si en algún momento posterior se quita mySprite, que va siendo quedarse en la memoria, porque se ha añadido en sí (o una referencia a sí mismo) a la etapa en el método init().

En este escenario, la mejor forma de evitar esto podría ser eliminar el oyente agregado al escenario cuando mySprite se elimina de la lista de visualización.

private function init(e:Event = null):void { 
     addEventListener(Event.REMOVED_FROM_STAGE,cleanUp); 
     stage.addEventListener(Event.RESIZE,handleStageResize); 

    } 

    private function cleanUp(e:Event):void { 
     stage.removeEventListener(Event.RESIZE,handleStageResize); 
    } 

estoy seguro de que otras personas le dirá a utilizar referencias débiles cuando se añade al oyente a la etapa, pero debe quitar sus oyentes de todos modos. Si no lo hace, cuando elimine mySprite de la lista de visualización y no tenga más referencias, será elegible para GC y eventualmente se borrará de la memoria. Pero hasta que eso suceda, el código en handleStageResize() continuará ejecutándose.

+2

+1 - La GC adecuada en flash es importante, y para muchas personas que son autodidactas, no es un problema obvio. – Bosworth99

0

No voy a publicar un ejemplo de esto, pero lo explicaré un poco. Hay 2 situaciones que estás describiendo aquí.

  1. pérdidas de memoria
  2. procesador
  3. desborda

AS3 se encarga de las operaciones de memoria y procesador diferente.

Las pérdidas de memoria ocurren cuando hay muchos objetos creados y destruidos. Los objetos pierden memoria cuando tienen referencias y el objeto se destruye sin destruir las referencias, lo que deja un bloque de memoria de un objeto no utilizado = fuga.

Los desbordamientos de procesador se producen cuando hay muchos métodos que se referencian entre sí sin "cerrar el ciclo".

4

Voy a seguir la respuesta de @ Juan: GC debe considerarse desde cero como un aspecto crítico del diseño de la aplicación. Si crea un objeto, debe tener en cuenta cada referencia al mismo, eliminar cada referencia y anularla para que marque correctamente @. Si hace referencia a ese objeto en una matriz, eso cuenta, si lo hace referencia en un oyente, eso cuenta, si lo hace a través de una variable local, eso también cuenta (aunque solo durante la vida de la función), si simplemente está en el lista de visualización, que definitivamente cuenta, y así sucesivamente.

Voy a escribir mis instrucciones de eliminación de escuchas antes de agregarlas solo para asegurarme.

Casi siempre escribiré un método público destroy() para que cualquier objeto maneje las jerarquías internas de los objetos (las llamadas parentales destroy en child, que, a su vez, destruyen cualquier elemento secundario, etc.). Simplemente eliminar/anular un padre sin hacerlo a cada niño es una gestión de GC pobre.

Y si realmente tiene alguna duda de que la fuga de mem ha surgido, trace el Sistema.totalMemory sólo para asegurarse de:

var mem:String = Number(System.totalMemory/1024/1024).toFixed(2) + ‘Mb’; 
trace(mem); // eg traces “24.94Mb” 

Medio - acaba de ser metódico en ello - no es una ciencia exacta, pero hay que tener cuidado.

Saludos -

@ e incluso si lo hace, flash hace su propia decisión acerca de cuándo realmente hacer un barrido. Lo mejor que podemos hacer es garantizar que un objeto esté correctamente marcado y confiar en que se tratará de manera eficiente.