|
-
Senior Member
[Disc] Garbage collection in AS3, methods and techniques.
I'm opening this thread in Garbage Collection techniques for AS 3.0, hoping it will become a sticky for those who are working with AS 3.0
This is the issue:As you may know AS 3.0 doesn't have the AttachMovieClip, CreateEmptyMovieClip or DuplicateMovieClip commands, instead you need to create a new instance of either a MovieClip, Bitmap or Sprite class (or an inherited class based on one of those) and then add this Instance to the display list via the addChild command. The process is fairly straight forward:
Code:
(pseudocode may have syntax errors)
var myClip:MovieClip=new MovieClip()
addChild(myClip)
//Adds an empty MovieClip to the display list (to the screen)
Also since _root no longer exists theres no way to keep track of your new instance unless you keep the Original MovieClip pointer (that is in our case the MyClip variable) or add it to an array, a list or just about any variable that can Hold a MovieClip pointer.
Code:
var MyClipArray=new Array()
MyClipArray.push(myClip);
You can also assign an Event to that movieClip like enterFrame
Code:
MyClip.addEventListener(events.EnterFrame,tick)
function tick(e:Event){
trace("Im Still Alive!")
}
Now you can apparently delete a movieClip, Bitmap, Sprite by Simply removing it from the screen
Code:
var i:String
for (i in MyClipArray){
removeChild(MyClipArray[i])
}
However if you do this example, you will still see the message
"Im Still Alive!"
Even if the MovieClip object has been removed.
The problem is the new VM in as 3.0 (like Java) does NOT perform automatic Garbage Collection, so removeChild WILL NOT remove the Clip from memory, or remove the eventlistener, therefore the MovieClip is in fact, "still alive" (going to an empty frame the main timeline,(gotoAndStop method) wont work either. since the GD isnt automatic there either)
So you will still keep seeing the trace message.
"Im Still alive!"
Until you close the application or the browser window. However you don't have access to the child anymore.
Of course, this can be a performance nightmare, if you create per example 100 particles in an enterFrame tick, "destroy them" and then add another hundred in the next, your performance may drop within minutes or even seconds. (depending on the nature of your particles)
Now afaik there are 3 known methods to deal with this.
1.-Use and Reuse your current objects.
I know, is not the most elegant method but it works, simply use the instance objects you already have on the screen, or create a limited number of objects (enemies per example) and reuse them as needed, it may sound silly but reusing objects is a technique gamedevs have been using for decades when they have to deal with memory issues and the results are good enough for small-medium projects and the like. (also this can be used in combination with method 3 keep reading)
2.-Carefully use AS3 garbage collection
Gargabe collection does work, but is not automatic, in our example we'd need to use removeEventListener, then removeChild to stop the event from ticking, however this WONT immediately destroy the object until the Garbage Collector kicks in.
Also if the object is a MovieClip you can try adding an Empty Frame then use gotoAndStop(emptyFrame), The object is still there in memory until the gc decides otherwise, but at least it wont bother us anymore.
Code:
var i:String
for (i in MyClipArray){
myClipArray[i].removeEventListener(Event.ENTER_FRAME)
removeChild(MyClipArray[i])
}
If you had added timers, listeners, references or any other link to it then you will have to remove it by hand as well.
note: Your performance mileage may vary using this method. Memory Leaks May occur if you are not careful enough.
3.-Use Bitmaps instead.
The method most professional AS 3.0 game developers are using. Pixel based bitmap Methods in as 3.0 are up to 10 times faster than their AS 2.0 Bitmap counterparts, so is now possible to use bitmaps to render our objects in AS 3.0 at pretty decent speeds, of course you will need to handle all the processing, updating and rendering of the game objects by your self, but the performance (if you are careful) may just be worth it. (besides is a nice change to use bitmap based games on flash at pretty decent speeds, depending on your screen size and optimization)
-Reusing MovieClips part2: another trick you can use, is to create single instances of movieclips and then use the bitmap.draw(movieClip) to render them on a bitmap screen instead of addChild. Difference is, a single MovieClip can represent hundreds of objects in the screen just like a bitmap.
note: This is not recommended if your game still depends heavily on Vector based MovieClips, or needs scaling, use prior methods instead.
So thats it, the discussion is open, please correct any errors I may (and probably did) committed in the explanation and feel free to add any method you recommend or use to deal with this problem.
Last edited by AzraelKans; 01-18-2008 at 02:52 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|