Foros del Web » Creando para Internet » Flash y Actionscript »

Cree un monstruo chupa memoria, que puedo hacer?

Estas en el tema de Cree un monstruo chupa memoria, que puedo hacer? en el foro de Flash y Actionscript en Foros del Web. Hola a todos, voy al grano, como lo dice el titulo he creado un monstruo que me está chupando la memoria como agua, a pesar ...
  #1 (permalink)  
Antiguo 16/02/2010, 10:25
 
Fecha de Ingreso: febrero-2010
Mensajes: 7
Antigüedad: 14 años, 9 meses
Puntos: 0
Cree un monstruo chupa memoria, que puedo hacer?

Hola a todos, voy al grano, como lo dice el titulo he creado un monstruo que me está chupando la memoria como agua, a pesar que intento descargar todo (unload) no le llego a como hacer para que sea "garbage collector material".

Una película principal se encarga de manejar cuatro links (detallaré 2 porqué son la misma cosa), estos llevan a una película que puede tener hasta 30 links, cada link puede cargar un SWF externo. El asunto es que para que sólo se pudiera cargar un SWF a la vez (Tratando de evitar un desborde de SWF), todo lo cargo en un loader común (cargadorInfo:Loader) y para que a la vez pudiera quitarlo del display list lo incluyo en una Sprite común (displayInfo:Sprite). Entonces, para que cada categoria en mi pelicula principal se asegure que descarga tanto el material del loader como del display list al momento de darle click este ejecuta esta función:

Código:
function borrarInfo() 
{ 
 
   if(lista_alumnos_mc.displayInfo.numChildren > 0) 
   { 
      lista_alumnos_mc.displayInfo.removeChildAt(0); 
      lista_alumnos_mc.cargadorInfo.unload(); 
   } 
    
   if(lista_alumnos_mc.displayFondo.numChildren > 0) 
   { 
      lista_alumnos_mc.displayFondo.removeChildAt(0); 
      lista_alumnos_mc.cargadorInfo.unload(); 
   } 
    
   //************************************************************* 
    
   if(lista_colegio_mc.displayInfo.numChildren > 0) 
   { 
      lista_colegio_mc.displayInfo.removeChildAt(0); 
      lista_colegio_mc.cargadorInfo.unload(); 
   } 
    
   if(lista_colegio_mc.displayFondo.numChildren > 0) 
   { 
      lista_colegio_mc.displayFondo.removeChildAt(0); 
      lista_colegio_mc.cargadorInfo.unload(); 
   } 
        
*/Aqui sigue el mismo cuento para los otros links, pero asi ya  
/*tienen una idea del desastre que me tengo 
}
Esta función se ejecuta cada vez que uno pincha en la película principal ya sea: Clases, colegio, profesores, eventos.

El código que va en la pelicula respectiva (lista_colegio_mc, lista_alumnos_mc...), y que es el responsable de cargarme sus respectivos SWFs, es el siguiente:

Código:
var fondo_info_mc:Sprite = new FondoAlumnosMc(); 
var displayInfo:Sprite = new Sprite(); 
var cargadorInfo:Loader = new Loader(); 
var displayFondo:Sprite = new Sprite(); 
 
function loadInfoContent() 
{ 
    
   addChild(displayFondo); 
   addChild(displayInfo); 
   displayFondo.addChild(fondo_info_mc); 
   fondo_info_mc.x = 1200; 
   fondo_info_mc.y = 70; 
   cargadorInfo.x = -250; 
   cargadorInfo.y = -250; 
   TweenMax.to (fondo_info_mc, 2, {x:250, y:70, ease:Expo.easeOut}); 
} 
 
 
//LISTA DE ALUMNOS CLASE 01************************************************ 
//******************************ALUMNOS******************************************* 
//*************************************************************************************** 
 
cl01_al01_btn.addEventListener(MouseEvent.CLICK, click_cl01_al01); 
 
function click_cl01_al01(evt:MouseEvent):void 
   { 
       
      loadInfoContent(); 
      var miRequest:URLRequest = new URLRequest("cl01_calderon_vega_edwin_jesus.swf"); 
      cargadorInfo.load(miRequest); 
      cargadorInfo.contentLoaderInfo.addEventListener(Event.COMPLETE, startListener); 
      function startListener (e:Event):void 
      { 
         displayInfo.addChild(cargadorInfo); 
      } 
   } 
//***************************************************************************** 
 
cl01_al02_btn.addEventListener(MouseEvent.CLICK, click_cl01_al02); 
 
function click_cl01_al02(evt:MouseEvent):void 
   { 
      loadInfoContent(); 
      var miRequest:URLRequest = new URLRequest("cl01_leiva_monge_melania.swf"); 
      cargadorInfo.load(miRequest); 
      cargadorInfo.contentLoaderInfo.addEventListener(Event.COMPLETE, startListener); 
      function startListener (e:Event):void 
      { 
         displayInfo.addChild(cargadorInfo); 
      } 
   } 
//**********
Esto se repite en todas las listas con todos los links, etc. Aqui puse dos links nada más para que puedan tener una idea de como está el código.

El asunto está en que no puedo dejar el cargadorInfo = null porqué me dispara problemas ya que es totalemente común y el problema mayor es que como dije, esto es un pozo sin fondo!!!.

Alguien me podría echar la mano para ver como puedo descargar de la memoria los SWF que cargo al momento de darle click a cualquiera de los links llamados "Colegio, clases..." en mi Movie principal.

Agradezco cualquier ayuda, como pueden ver en el código soy bastante nuevo en esto y la verdad es que no sé como para donde salir corriendo al ver como me DRAGA la memoria el bichito este que me inventé :lol:.

Saludos y gracias por su tiempo.
  #2 (permalink)  
Antiguo 16/02/2010, 10:46
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Cree un monstruo chupa memoria, que puedo hacer?

Mira.. no he leido ni interpretado tu codigo, pero se a que te refieres con chupar memoria, sobre todo en proyectos grandes.

Para que el Garbage Collector esté activo de manera a eliminar funciones X cuando ya no son requeridas debes declararlo en tu Listener.. alguna vez escribi sobre esto, pero lo unico que recibi fueron palos.

Te pongo un ejemplo para que puedas adaptarlo a tu poyecto, y espero te sirva de modelo con un listener cualquiera:

Código:
botn.addEventListener(tipoEvento.NOMBRE_EVENTO, funcion, userCapture, priority, weakReference);
Bueno, la estructura normal ya la conoces, o sea

intancia.addEventListener... dentro de este listener ponemos el famoso parametro o tipo de evento MouseEvent.MOUSE_DOWN, y luego el nombre de la funcion que invoca, llamale como quieras.

los otros elementos son:

en rojo el userCapture, que nos permitira controlar el flujo de eeventos, pero no se si te sera util ahora, por ende, el parametro debes declaralo por defecto en FALSE

en azul, esta el priority, que nos permite asiganale prioridades segun el orden que queremos organizar nuestros detectores, por lo general va un numero entero, donde a mayor sea el numero, mayor prioridad ganara con respecto a los otros listener.. mientras puedes dejarlo en cero, total, no tienes ese problema

y en verde, tu posible camino de luz, o sea el weakReference, que por defecto viene como FALSE, y activa el Colector de basura en AS 3, y actua cuando ya no se esta referenciando ese listener en el proceso... por lo general ocurrira cuando se detenga la funcion, o se elimine el listener, mediante removeChildAT, o bien un removeEventListener. Como viene en FALSE, debes cambiarlo a True.

La sintaxis de tus listener debe quedar asi:

cl01_al01_btn.addEventListener(MouseEvent.CLICK, click_cl01_al01, false, 0, true);

entonces ya habilitas en Garbage collector para elimnarlo de tu memoria cuando ya no este en uso... asi que estos ultimos parametros te serviran para tal efecto, y actuara de pastilla de chikitolina para tu monstruo.

Espero te sirva.. lo quite de algunos libros, y la documentacion de adobe, cuando tuve un problema similar
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...
  #3 (permalink)  
Antiguo 16/02/2010, 11:45
 
Fecha de Ingreso: febrero-2010
Mensajes: 7
Antigüedad: 14 años, 9 meses
Puntos: 0
Respuesta: Cree un monstruo chupa memoria, que puedo hacer?

Amigo, creo que le diste una estocada mortal a mi creación, sin duda por aquí va el camino porqué tenía que eliminar no sólo el loader, quitarlo del Display list PERO también eliminar el listener y ahí no estaba claro de como hacerlo "weakReference", he leido como hacerlos weak pero nada tan claro como lo que me recomiendas.

Sin duda voy a entrarle a palos al código de una y te informo, pero desde ya quedo agradecido por tan gran AYUDA!!!

Un saludo y en un par de horas de cuento como me fue. Sin duda será de mucha ayuda para muchos usuarios tu aporte.
  #4 (permalink)  
Antiguo 16/02/2010, 12:47
 
Fecha de Ingreso: febrero-2010
Mensajes: 7
Antigüedad: 14 años, 9 meses
Puntos: 0
Respuesta: Cree un monstruo chupa memoria, que puedo hacer?

Bueno ya lo implementé, pero parece que aun no puedo eliminar los SWFs de la memoria, cada click en los links sube y sube y sube la memoria.

loncho_rojas yo sé que podría ser mucha molestia revisar mi código para ver que puede ser el problema porqué a pesar que desde el Movie principal descargo los loaders, los quito del display list y ahora dejo el listener como weakreference no me eliminan los SWF cargados de la memoria, lo sé porqué le di tiempo para que pasara el GC pero nada, ahora lo forcé llamando el método: flash.system.System.gc(); y nada, la memoria sigue igual de embotada.

Esto casi que se vuelve “filosofando en AS3”: Que fácil que es agregar cosas en la vida, pero que difícil deshacerse de ellas.

Fuera de eso, ¡que frustración!, ¿Qué más podría eliminar aparte del Main.fla? jeje.
  #5 (permalink)  
Antiguo 16/02/2010, 14:08
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Cree un monstruo chupa memoria, que puedo hacer?

Y bue... la verdad que para liberar memoria, hay distintos procesos, ya sea si son Bitmaps, sonidos etc...

Mira este enlace, hay una fragmento que habla del Garbage collector, para liberar archivos externos, con una funcion unloadAndStop();...

http://www.slideshare.net/albertx/ad...tion-script-30

no te leas el archivo que esta en el slide, lee el articulo desarrollado mas abajo, que habla de eso.. o bajate el archivo.. tal vez te brinde una idea mejor..

sobre todo estas lineas.. capaz te brinden una pista:

Cita:
# Loader.unloadAndStop()
# Problemas con la carga de elementos gráficos externos (Loader)
En ocasiones los sonidos no se detenían cuando descargábamos un video u otro swf con audio.
El recolector de basura no podía eliminar la película cargada incluso aunque ya no la estuviéramos ocupando.
Los video se seguían reproduciendo por “detrás” aún cuando ya no se ocupaba el clip.
# Loader.unloadAndStop()
Disponible desde Flash Player 10
Pasa por todo el árbol de “DisplayObjects” del swf cargado realizando lo sig:
Libera memoria de mapas de bits
Detiene la ejecución de los sonidos
Detiene la ejecución de los videos
Detiene todas las animaciones de los MovieClips
Elimina los “handlers” para los eventos enterFrame, frameConstructed, exitFrame, activate, deactivatey eventos de stagede los elementos internos
Detiene cualquier carga de datos que se esté ejecutando desde los elementos internos (FileReference, sockets, http, file:)
Todas las instancias de la clase << Timer >> son detenidas
Cámara y Micrófono son apagados
El DisplayObjectno se puede volver a mostrar en el Flash Player.
Porque usas 2 If similares en tu funcion de eliminar removeChildAt();, o sea, no siilares, repetidas mejor dicho.

Lastimosamente no tengo tanto tiempo, puesto que me gusta este tipo de cosas, donde hay objetos misteriosos que no funcan como queremos, o si no, tal vez lo analizaba por mi cuenta tambien, pero el tiempo apremia, y solo te puedo orientar, sobre cosas que ya lei antes.
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...
  #6 (permalink)  
Antiguo 16/02/2010, 15:00
 
Fecha de Ingreso: febrero-2010
Mensajes: 7
Antigüedad: 14 años, 9 meses
Puntos: 0
Respuesta: Cree un monstruo chupa memoria, que puedo hacer?

El problema es que estoy aun con el CS3 (Flash 9), pero sin duda voy a darle una revisada al link que me diste.

Muchisimas gracias por tu tiempo y ayuda, no te preocupes que fueron de gran avance.

Un gran saludo y paz desde Costa Rica.
  #7 (permalink)  
Antiguo 26/02/2010, 12:21
 
Fecha de Ingreso: febrero-2010
Mensajes: 7
Antigüedad: 14 años, 9 meses
Puntos: 0
Respuesta: Cree un monstruo chupa memoria, que puedo hacer?

Hola amigos, sigo con el mismo problema y no puedo llegarle a una solución.
Cambié la forma de buscar una solución y apesar de que utilizo todas las herramientas que he podido encontrar NADA parece que puede eliminarme el swf cargado de la memoria.

Utilizo: el metodo unloadAndStop(Cambie a CS4 a ver si acaso)
Utilizo: weak references
Utilizo en el SWF que será cargado un REMOVE_FROM_STAGE que dispara una funcion Destroy que elimina listeners y objetos.

Apesar que uso todo esto, el bendito SWF sigue clavado ahi en la memoria.

Este es el código que tengo en el SWF que será cargado:

Código:
addEventListener(Event.ADDED_TO_STAGE, addedHandler);
addEventListener(Event.REMOVED_FROM_STAGE, removedHandler);

var logo_mc:MovieClip = new LogoMc();

function addedHandler(evt:Event):void
{
	removeEventListener(Event.ADDED_TO_STAGE, addedHandler);
	initAnimation();
}

function removedHandler(evt:Event):void
{
	removeEventListener(Event.REMOVED_FROM_STAGE, removedHandler);
	//Here comes the destroy function
	destroy();
}

function initAnimation():void
{

	addChild(logo_mc);
	logo_mc.x = 100;
	logo_mc.y = 200;
	logo_mc.addEventListener(Event.ENTER_FRAME, logoMove);
	
}
	
function logoMove(evt:Event):void
	{
		logo_mc.x += 10;
	}
	
function destroy():void
{
	logo_mc.removeEventListener(Event.ENTER_FRAME, logoMove);
	logo_mc = null;
}
Este es el código que puse en el Movie principal

Código:
var contentLoader:Loader = new Loader();
addChild(contentLoader);

loadButton_btn.addEventListener(MouseEvent.CLICK, loadMySwf, false, 0, true);
unloadButton_btn.addEventListener(MouseEvent.CLICK, unLoadMySwf,false, 0, true);


function loadMySwf(evt:MouseEvent):void
{
	loadURL("mySwfTest.swf");
}

function loadURL(url:String):void
{
	contentLoader.unloadAndStop();
	var request:URLRequest = new URLRequest(url);
	contentLoader.load(request);
}


function unLoadMySwf(evt:MouseEvent):void
{
	if(contentLoader.content)
	{
		contentLoader.unloadAndStop();
	}
}
Apesar de ser el SWF más simple del mundo y con todas estas formas de buscar desaparecerlo de la memoria NADA, el bicho sigue ahí.

Gracias por cualquier consejo o si encuentran una forma de hacerlo con exito les agradecería que me echaran un cable.
  #8 (permalink)  
Antiguo 26/02/2010, 18:24
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Cree un monstruo chupa memoria, que puedo hacer?

mmm.. puede que estos links tengan razon.. habla de falencias en el flash player, con la recoleccionde basura.. esta muy interesante, y bien argumentado... solo que hay tanta gente desprestigiando a flash que de repente nos volvemos reacios a estas cosas... pero puede tener razon.. esta en ingles.. traducelo, y tal vez te ilumnine

LINK 1

LINK 2

Tambien puedes intentar esto que nosotros hicimos, pero con resultados no 100% satisfactorios, pero se aplicaba muy bien a nuestra problematica.. aunque deberias ver si es tu caso, dado que vi que usas una clase denominada Tween, que veo estas emulando cuando creas tu contenedor...

Cita:
cargadorInfo.x = -250;
cargadorInfo.y = -250;
TweenMax.to (fondo_info_mc, 2, {x:250, y:70, ease:Expo.easeOut});
aunque no se si es el caso, dado que no haz expuesto el uso del Tween

basicamente la solucion del link expone:

Cita:
Pero claro ahora tenemos un garbage collector que algunos claman que funciona y yo en lo personal digo que apesta.

Si ha alguien le ha pasado esto es muy sencillo de resolver tan solo hay que poner la variable del tween como una variable de clase y no como una variable local de la función.

chekalo

Espero te sirva.. creo que lograras resolverlo
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...

Última edición por loncho_rojas; 26/02/2010 a las 18:50

Etiquetas: memoria
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:34.