Jump to content
GreenSock

Amnesicat

Dispose method for SWFLoader

Recommended Posts

Hi all

 

I'm loading and unloading child SWFs from a main SWF using the Main SWF Code below that was suggested in another thread on this forum. Then as suggested in the SWFLoader API documentation I added a dispose method to the Child SWFs to cleanup eventlisteners for garbage collection when unload is called within the Main SWF (See Child SWF Code below).

 

The trouble is that when I test the memory management of the Main SWF there seems to be a memory leak, as the memory isn't being released and is building up over time. I am pretty new to actionscript and not really sure what else I have to do to avoid memory leaks when loading and unloading with SWFLoader. Is there something else I need to add in the dispose method of the Child SWF?

 

I'd appreciate any help.

 

Thank you

 

Main SWF Code:

import flash.display.*;
import flash.events.*;
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;

var page1:SWFLoader = new SWFLoader("page1.swf",{centerRegistration:true,x:512,y:350});
var page2:SWFLoader = new SWFLoader("page2.swf",{centerRegistration:true,x:512,y:350});
var page3:SWFLoader = new SWFLoader("page3.swf",{centerRegistration:true,x:512,y:350});
var currentPage:SWFLoader;

nav_mc.button1.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
nav_mc.button2.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
nav_mc.button3.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
nav_mc.button1.mouseChildren = false;
nav_mc.button2.mouseChildren = false;
nav_mc.button3.mouseChildren = false;
nav_mc.buttonMode = true;

function clickHandler(e:MouseEvent):void
{
var next:SWFLoader;
if (e.currentTarget == nav_mc.button1)
{
 next = page1;
}
else if (e.currentTarget == nav_mc.button2)
{
 next = page2;
}
else
{
 next = page3;
}
if (next == currentPage)
{
 return;
}
if (currentPage != null)
{
 removeChild(currentPage.content);
 currentPage.unload();
}
currentPage = next;
currentPage.load(true);
addChild(currentPage.content);
}

 

 

Child SWF Code:

import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
import flash.events.MouseEvent;
import flash.display.*;
TweenPlugin.activate([scalePlugin]);

var mcArray:Array = [pic1,pic2,pic3,pic4,pic5,pic6,pic7,pic8,pic9,pic10,pic11,pic12];
var mcTween:TimelineMax;

TweenMax.to(mcBackDrop, 0, {autoAlpha:0});

var len:int = mcArray.length;
var mc:MovieClip;

for (var i:int = 0; i < len; i++) {
mc = mcArray[i];
var stageX = stage.stageWidth / 2;
var stageY = 330;
mc.mouseChildren = false;
mc.addEventListener(MouseEvent.CLICK, clickHandler, false, 0, true);
mc.mcTween = new TimelineMax({paused:true,reversed:true,onReverseComplete:addBackDrop});
mc.mcTween.insert(TweenMax.to(mcBackDrop,0.8,{autoAlpha:0.7,ease:Sine.easeInOut}));
mc.mcTween.insert(TweenMax.to(mc,1,{x:stageX,y:stageY,scale:1,ease:Back.easeInOut}));
}

function clickHandler(e:MouseEvent):void
{
e.target.mcTween.reversed = ! e.target.mcTween.reversed;
e.target.mcTween.resume();
addChild(e.target as DisplayObject);
}

function addBackDrop()
{
addChild(mcBackDrop);
}

var curParent:DisplayObjectContainer = this.parent;
while (curParent) {
if (curParent.hasOwnProperty("loader") && curParent.hasOwnProperty("rawContent")) {
	Object(curParent).loader.addEventListener("unload", dispose, false, 0, true);
}
curParent = curParent.parent;
}

function dispose(event:Event):void {
mc.removeEventListener(MouseEvent.CLICK, clickHandler);
}

Link to comment
Share on other sites

I doubt this would cause any major problems, but it would be best to kill() the timeline that you created in the child swf(s) by adding this line to your dispose() method:

mc.mcTween.kill();

 

Keep in mind that it is perfectly normal for memory usage to increase over time, but then at some point (when Flash decides it wants to), Flash will run a garbage collection routine to free up memory. So you need to make sure you watch the memory for a WHILE and see if it goes back down. If not, then you very likely have a memory leak. But don't assume after watching memory usage increase for 90 seconds that there's a memory leak. Give it some time.

 

There could be a lot of reasons for your memory leak and it's difficult to diagnose by just looking at the snippets you provided - like maybe you have some audio playing or NetStreams or some other objects that persist in memory. Hopefully this gives you a few ideas to try. Let us know if you figure it out or need more help.

Link to comment
Share on other sites

Hello Mr Greensock

 

Firstly, I know you probably get compliments on your classes all the time, but I just have to say that they are an extremely intuitive and superbly crafted set of classes. I used them in my last project when I only just started learning actionscript, and as a beginner I found them really easy to implement and right away started accurately tweening to my heart's content. I didn't realise that this coding stuff could be so fun (I am merely a graphic designer trying to cut corners by doing my own AS coding). So, a big thank you for that.

 

Well, I tried adding mc.mcTween.kill(); to the dispose method, and as you said it didn't make any difference. There's definitely memory building up as you click each page button, and it just keeps building the more you click and not fully releasing even after leaving it run for at least 20 mins. I have attached some simple example FLAs if you wanted to have a look. The code is exactly what I'm using in my final project except obviously it includes bitmap images instead of the vectors.

 

I think I have narrowed the problem down to the use of the TimeLineMax instance within the for loop. If I just use the loop to capture all the objects and only add a simple tween in a separate function it seems to work fine without any memory build up. Should I not be instantiating a TimeLineMax in a loop like that? Should I use some other method to tween and reverse tween multiple objects?

 

On another note, I have been using Mrdoob's Hi-Res Stats profiler for testing memory. Have you used this at all?, and if so, is it a reliably consistent profiler?. I ony ask because I've been getting varying results depending on which Flash Player version I use. For instance, with other memory tests I've performed (not the particular problem I'm experiencing now, interestingly) using Flash Player version 10.1 and above the profiler would show memory being captured and not released after the child swfs are loaded and unloaded repeatedly. But, using Flash Player 10 and below it would show the memory build and release as the garbage collection passed over, as it should. So, I'm definitely no expert in the matter and by no means trying to bag Mrdoob's profiler, I'm just wondering if there may be a chance it could be a miss reading or bug in this particular profiler or something. Is there a reliable memory profiler that you would recommend using? Is the Flash (Flex) Builder version any good?

 

Any help would be terrific, because I'm really baffled by this one.

Thanks.

Example.zip

Link to comment
Share on other sites

I see the problem. You're creating a TimelineMax for EACH element in your mcArray, but in your dispose() method, you're ONLY calling kill() on one of them. So all the others persist and prevent the swf from completely unloading and becoming eligible for gc.

 

So in your dispose() method, add this:

 

for (var i:uint = 0; i < len; i++) {
   mcArray[i].mcTween.kill();
}

Link to comment
Share on other sites

Yep, that seems to have nailed it. Tested it on my mates version of the Flash Builder Prolifer and it stayed at a happy yoyo with the gc. I did not know you could do that with for loops. Thank you so much for showing me the way, greatly appreciated.

 

Cheers.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×