PDA

Volledige versie bekijken : Memoryleak; AS3 Slideshow via documentClass


Neejoh
%Europe/Berlin %533 %2008, 13:47
Met onderstaande code loopt mijn geheugen van de browser (of player) vrij snel vol. Ik gebruik fullscreen afbeeldingen tussen de 100-400kb en de slideshow draait een gehele dag. Als het geheugen dus een aantal MB per uur oploopt gaat dit voor problemen zorgen.

Onderstaande code is de Document Class van een lege .FLA

slides.as
/**
* Slideshow with memoryleak
* Any help would be much appreciated!
* @email <r.terveen@comsi.nl>
*
* @original Chris Brimelow
* @url http://chrisbrimelow.com/blog/?p=20
*/
package
{
import flash.display.MovieClip;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.*;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.Timer;
import fl.transitions.Tween;
import fl.transitions.easing.*;

public class slides extends MovieClip
{
var xmlLoader:URLLoader;
var theXML:XML;
var durationSlide:uint=2000;//-- miliseconds
var durationFade:Number=1;//-- seconden
var photos:XMLList;
var photoLoader:Loader;
var photoArray:Array;
var fade:Tween;
var curr:Number;
var timer:Timer;

public function slides():void
{
xmlLoader=new URLLoader;
xmlLoader.load(new URLRequest("images.xml"));
xmlLoader.addEventListener(Event.COMPLETE,getXML);
photoArray=new Array;
curr=0;
timer=new Timer(durationSlide);
timer.addEventListener(TimerEvent.TIMER, switchPhoto);
photoLoader = new Loader;
}

private function getXML(e:Event):void
{
theXML=new XML(e.target.data);
photos = new XMLList(theXML.websiteinfo.photos.photo);

for (var i:int=4; i < photos.length(); i++) {
photoArray.push(photos[i].@url);
}
timer.start();
switchPhoto(null);
}

private function switchPhoto(e:TimerEvent):void
{
if (curr < photoArray.length) {
photoLoader.load(new URLRequest(photoArray[curr]));
photoLoader.contentLoaderInfo.addEventListener(Eve nt.COMPLETE,fadeSlide);

trace("loading: " + photoArray[curr]);
curr++;
} else {
curr=0;
switchPhoto(null);
photoLoader.unload();
trace("unloading...");
}
}

private function fadeSlide(e:Event):void
{
stage.addChild(photoLoader);
fade=new Tween(photoLoader,"alpha",Regular.easeOut,0,1,durationFade,true);
}
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<mywebsite>
<websiteinfo>
<information>Bla bla bla yada yada.</information>
<photos>
<photo id="1" url="images/mydirectory/Animals.jpg" />
<photo id="2" url="images/mydirectory/animals_up_for_adoption.jpg" />
<photo id="3" url="images/mydirectory/main-eagle.jpg" />
<photo id="4" url="images/mydirectory/funnyanimals.jpg" />
<photo id="5" url="images/mydirectory/giraffe.jpg" />
<photo id="6" url="images/mydirectory/Twins1.JPG" />
</photos>
</websiteinfo>
</mywebsite>

In de constructor vraag ik de XML op, start ik de timer (2000 ms), maak een nieuwe loader container voor de afbeeldingen.
De timer roept de functie switchPhoto() aan, die kijkt of hij alle items uit de XML gehad heeft, is dit het geval leegt hij de container.

Iemand een idee waar het mis gaat?

mknol
%Europe/Berlin %939 %2008, 23:32
Je moet zowiezo de eventlistener removen bij het aanroepen van de fadeSlide.
Ook zou ik een onComplete handler toevoegen aan je tween. Hier kun je de tween deleten, en evt. andere sprites deleten. De movie blijft nu alleen maar sprites aanmaken, dit zorgt ook voor veel geheugengebruikt, aangezien alle foto's blijven bestaan (en op elkaar geladen worden?)

Neejoh
%Europe/Berlin %551 %2008, 14:14
Probleem lijkt nog niet opgelost. Het zou kunnen dat het door de tween komt... Hoe kan ik deze verwijderen?
fade = null; lijkt niet te werken.
private function removetimeDisp(e:Event):void
{
photoLoader.contentLoaderInfo.removeEventListener( Event.COMPLETE, removetimeDisp);
contSlideshow.addChild(photoLoader);
fade=new Tween(photoLoader,"alpha",Regular.easeOut,0,1,durationFade,true);
fade.addEventListener(TweenEvent.MOTION_FINISH, finishedSlide);
}

private function finishedSlide(e:Event):void
{
trace('remove tween');
fade = null;
}

marcvz
%Europe/Berlin %765 %2008, 19:21
fade = null werkt niet omdat je nog een listener aan de tween hebt hangen.
Ik zet zelf altijd weakreference op true op m'n listeners. Dan voorkom je leaks doordat je listeners vergeet te verwijderen.

Misschien is het ook het overwegen waard om een andere tween engine te gebruiken. Zijn genoeg beter te vinden dan de buildin Tween class.

Iasonic
%Europe/Berlin %522 %2008, 13:31
Kijk eens even naar je functie!
timer.addEventListener(TimerEvent.TIMER,switchPhot o);

switchPhot bestaat niet!
misschien dat dit je probleem oplost.

Jan
%Europe/Berlin %531 %2008, 13:44
Dat komt door het forum. Als je te lange woorden(opeenvolging van 50 letters zonder spaties) gebruikt dan plaatst het forum er zelf een spatie tussen. In Flash zal zijn script wel juist zijn, want een spatie op die plaats levert een duidelijke compiler error op.

Geen spaties:
timer.addEventListener(TimerEvent.TIMER,switchPhot o);
opgelost door zelf een spatie achter ( en , te zetten:
timer.addEventListener( TimerEvent.TIMER, switchPhoto);

Groeten,
http://users.telenet.be/jansurf/cwo.png Jan

Mr. Black
%Europe/Berlin %531 %2008, 13:45
Is een bug van het forum. Na 25 tekens zet hij automatisch een spatie, of zoiets. :)

Topic is trouwens al 2 weken dood... ;)

Iasonic
%Europe/Berlin %619 %2008, 15:51
Ow haha had die o met spatie niet eens gezien!