My question is as simple as the title, yet googling it didn't give me a simple yes/no answer.
Does AS3 have a class destructor?
In short: no, it doesn't. Flash Player virtual machine uses garbage collector concept. You don't have direct control over memory used by objects (except for rare cases like BitmapData.dispose() and ByteArray.clear()), but you are to do some work to make garbage collecting possible. And there is no way you can have something triggered automatically when an object dies.
Follow the links to learn more about GC logics.
Related
I'm working on a flash game that has developed an obvious memory leak. I do what I'm supposed to do with GC; remove all references to the object, nullify it, remove all listeners (or use weak listeners); but the leak is still present.
I've stumbled across this article:
http://www.andymoore.ca/2010/03/motherfucking-as3-garbage-collection/
It claims that objects that are too large will never be garbage collected. This theory fits well with my project since all of my game resides in a couple of huge MovieClips that are created and destroyed often.
Is there any merit to the claim that objects that are too large will never be garbage collected?
I've worked on multiple mid-size to large-size project and the leak you describe seems to be a problem of recursive disposal. You need to really introspect your object from the most nested item and start disposing from that point (stop, nullify, dispose bitmapdata and remove listeners).
I suggest that you take a look at those:
A nice profiler:
https://code.google.com/p/flashpreloadprofiler/
Quasimondo developer on the aviary suite experiencing problem with large bitmap and showing an application that simulate memory assignation:
http://www.quasimondo.com/archives/000691.php
http://www.quasimondo.com/examples/memoryhog.html
Also for more resources on GC issues I suggest you use the Adobe Jira and Bugbase system:
https://bugs.adobe.com/
I do not think there are any merit to that claim. Also read Andy Moore comment:
So doing a quick pass of on-death = null codes, I halved my memory
footprint. I was able to drop that by a further 80% by commenting out
all my “.cacheAsBitmap = true” statements.
You can try using SWFWire Debugger to see exactly which objects aren't being collected.
Disclaimer: This is my own project
I have a question how can I clear/free memory in flash? For example I am finishing game and I want to start from beginning and if I will just jump to the first frame all the objects there are still in this memory, is any possibility to force cleaning memory?
Can I free memory for an object? for example I removeChild(something) - and I want to free memory for an object as I will reuse it?
Can anybody explain me how the engine works?
Thanks
I would encourage you to read Chapter 14, Garbage Collection in the "Moock Book" (Essential ActionScript 3.0 by O'Reilly Publishing).
The short answer to your question is that you're not in control of de-allocation, the garbage collector is. In a garbage-collected language like AS3 or Java, you don't have manual control over allocation and de-allocation of memory like you do in lower level languages; there are no AS3 equivalents to things like delete in C++ or free in C. Your goal should not be controlling when you destroy things, but rather not forgetting to remove references to things you no longer need around and making sure you disable things that you intend for garbage collection.
Memory leaks in AS3 typically come from a mixture of newbie misunderstanding (like thinking removeChild or setting a reference to null destroys objects), and from not keeping good track of references to objects--especially where strong listeners are involved.
A previous respondent posted this:
myObject = null;
What this does is remove a reference to the object that the variable myObject was holding. Nothing more. You need to know a lot more about the situation in order to be able to say whether this assignment even makes the object in question eligible for garbage collection, especially how many other variable are holding references to the object. And the object might already be eligible for garbage collection even if you didn't set the reference to null (i.e. if myObject has no connection to a GC root).
Suffice to say, the entire GC mechanism is more complex than can be satisfactorily explained in a StackOverflow post. That's why it has a whole chapter in the Moock Book, and even that book does not go into implemenation detail or great detail about when exactly the Flash Player does its ref counting deletions or mark and sweep passes.
The most important things to remember are, IMHO:
When you intend to "kill" an object, give it a cleanUp() or destroy() function where you do things like stop all its timers, sounds, remove listeners, etc. An object will continue to exist and execute code until it gets GC'd. And the Flash Player defers GC as long as it can--it's usually triggered when the Player needs to allocate more RAM from your system, because allocating memory is about the only thing that's more time consuming than doing the mark and sweep GC pass.
Read about weak vs strong listeners. Basically, when you have a weak listener, the listener reference is one that is ignored by mark-and-sweep GC, so it alone will not prevent an object from getting collected. But don't listen to anyone who tells you "always use weak" or "always use strong listeners and manually remove them" because there are times where each is appropriate, and that's why the choice is yours.
removeChild() will remove object from stage, but will still keep it in memory. You will have to null the object like this myObject = null if you wish to get rid of it entirely. You might not need to do that thought. Just removing it from stage and removing all associated events will be sufficient in most cases.
Clearing memory is a tricky thing with Flash, the proper way ow implementing it setting up objects properly in the first play for easy clearing, rather than forcing deletion. When you want to remove an object from memory, you do it by removing any reference to it, and then flash marks it for garbage collection. Then Flash at a later point removes the object from memory.
In order for the object to be ready for data collection it cannot have any connection to another object.
so if you have an object that has a single connection to a MovieClip and the movie clip has no other relation, then if you set it to null, you will remove it.
if you, however, have two objects that point to it, if you remove one link by setting it to null, the MovieClip will not be removed.
furhtermore, if you have a 2 or more movie clips that have a network of connections, removing those objects requires these connections be broken as-well. For example if you have a level with many characters and listeners set up, removing the lavel movieClip will not clear it.
one way of breaking these connections is adding onRemovedFromStage Events, that remove further children, listeners and objects. I've started using the casaLib extension of movieclip - CasaMovieClip, that has a function called removeChildrenAndDestroy. this makes it a bit easier, but would take a while to implement on an older project.
Anyhow, you'll find there are many sites discussing this, a good place to start is grant skinner's blog
My professor gave my class an assignment today based on object oriented programming in Pygame. Basically he has said that the game that we are to create will be void of a main game loop. While I believe that it is possible to do this (and this question has stated that it is possible) I don't believe that this is required for adherence to the Object Oriented paradigm.
In a diagram that the professor gave, he showed the game initializing and as the objects were instantiated the control flow of the program would be distributed among the objects.
Basically I believe it would be possible to implement a game this way, but it would not be an ideal way nor is it required for Object Oriented adherence. Any thoughts?
EDIT: We are creating an asteroids clone, which I believe further complicates things due to the fact that it is a real time action game.
Turn based games or anything event driven would be the route to go. In other words, take desktop GUI apps. They'll just tick (wait) over until an event is fired. The same could be done for a simple game. Take Checkers for example. Looping each game cycle would be overkill. 90% of the time the game will be static. Using some form of events (the observer design pattern would be nice here) would provide a much better solution. You're using Pygame, so there may be support for this built in, through due to my limited use I cannot comment fully. Either way, the general principles are the same.
All in all it's a pretty rubbish assignment if you ask me. If it's to teach you event driven programming, a simple GUI application would be better. Even the simplest of games us a basic game loop, which can adhere to OO principles.
Hmm. In the general case, I think this idea is probably hokum. SDL (upon which PyGame is implemented), provides information to the program via an event queue, and consuming that queue requires some sort of repeatedly checking the queue for events, processing them, and waiting until the next event arrives.
There are some particular exceptions to this, though. You can poll the mouse and keyboard for their state without accessing the event queue. The problem with that is it still requires something like a loop, so that it happens over and over again until the game exits.
You could use pygame.time to wait on a timer instead of waiting on the event queue, and then pass control to the game objects which poll the mouse and keyboard as per above, but you are still 'looping', but bound by a timer instead of the event queue.
Instead of focusing on eliminating a main loop, how about instead think about using it in an object oriented way.
For instance, you could require a 'root' object, which actually has its own event loop, but instead of performing any action based on the incoming events, it calls a handler on several child objects. For instance when the root object recieves a pygame.event.MOUSEBUTTONDOWN event, it could search through it's children for a 'rect' attribute and determine if the event.pos attribute is inside that rect. if it is it can call a hypothetical onClick method on that child object.
I think it might qualify as event driven programming? Which can still be object oriented. You see this in Flash a lot.
There's a difference between a main loop in a main class. You can still have a game class initialize all of your objects, and then rely on inputs to move the game onward.
Kinda hard to say exactly without knowing the exact parameters of your assignment, the devil is in the details.
You might look at how python utilizes signals. A decent example I found is at: http://docs.python.org/library/signal.html
I am writing a game in AS3 and have, as an example, around 40 objects on screen. Let's say they are clouds. I'm wondering which of the two paths would be less a strain on system resources:
a) Put an eventListener on each object and have it update itself, or
b) Loop through the array and manually update each object
Or is the performance difference negligable? Does either solution scale better than the others?
I would expect the performance to be fairly negligable either way. Once you get a lot of objects you might see a difference (with the loop being the winner). From my experience Adobe put a lot of work into optimizing the actionscript event listener path.
This is a tricky one, purists would say to to go with the array looping method, as with this method it would be possible to cut out the 'view' out of the MVC and still have the system working (which is a good test of any system). However, if you are working with the events you can cut some corners with event bubbling and strict typing.
For example if we assume you make a custom event called CloudEvent that has a property called cloud that contains a reference to the dispatching CloudSprite, then as long as the event bubbles by default, you don't need to add an event listener to each one, just to the DisplayObjectContainer which holds them (which I am imaginatively calling CloudContainer). This way the event bubbles up and you only have to add one listener, and don't have to worry about managing listeners on child items.
public function CloudContainer()
{
super();
addEventListener(CloudEvent.CHANGE, cloudChangeHandler);
}
private function cloudChangeHandler(evt:CloudEvent):void
{
var cloud:CloudSprite = evt.cloud;
cloud.update();
}
Hope this helps
I am under the impression that event listeners require more resources so it is better to use an array when performance is required. It would also scale better for that reason. If you are using Flash 10 then use a Vector, I believe it offers better performance than an array (and type saftey).
Use EventListeners! Just make sure you manage them properly ie. remove them when you done, use weak references.
You wont really find much performance from doing things like this. Usually better performance comes from the bigger ticked items, like not using filters, lowering the frame-rate etc. So punishing your code clarity and OO for the sake of a half a millisecond is not worth it in my book.
There are a few really great guides out there that will teach you all about optimizing in AS3. The best one I have found is Grant Skinner's; AS3 Resource Management. And I just found a quicker seven step version. I would definitely recommend everyone doing AS3 should read the Grant Skinner slides though.
Of course don't just take my word (or anyone else answering your question), you can do you own tests and actually see whats up using a profiler. See Lee Brimlow's latest video tutorial for how to do this. It is worth the watch! Check it out here: GotoAndLearn - ActionScript 3 Performance Testing.
My website is entirely flash based, it moves around a 3D model which was given to me as chunks of video that I've converted to FLV files. I'm using the FLVPlayback component to control the video inside of my program. While running memory checks using System.totalMemory I've noticed that whenever a video is loaded, it will eat up a chunk of memory and even when I remove all the event listeners from it(they are all weakly referenced), remove the component from its parent, stop the video and null the component instance, it still will not give that memory back.
This has been bothering me since I started working on this project because of the huge amount of video a user can potentially instantiate and load. Currently every video is loaded into a new FLVPlayback instance whenever it is required, but I have read that perhaps the best way to go about this problem is to simply have a global FLVPlayback instance and just reload the new video into the old instance, that way there would only be one FLVPlayback component in the application's memory.
Has anyone else run into this problem as well? Have you found a better solution than using a global instance that you just re-use for every new video?
I've never really liked the components, they're a bit dodgy. This particular problem seems to be common, and the somewhat annoying solution is, as you're suggesting, to only have one FLVPlayback and reuse that.
Here's a blog post about it
You can't help the memory problems much until Flash adds destructors and explicit object deletion, unfortunately. See this thread:
Unloading a ByteArray in Actionscript 3
There's a limit to how much memory Flash applets can use; the GC seems to fire upon reaching that limit. I've seen my memory-easy applets use as much as ~200MB, just because they run for hours on end and the GC doesn't want to kick in.
Oh, and I don't think using a single instance is an elegant solution, either. Currently I just write a dispose() function for my custom classes, waiting for some day when it can be turned into a proper destructor.
From what I gather after a lot of testing is that flash dynamically loads in libraries and components as needed but never garbage collects that data. For instance, if I have a website or an Air app that uses the FLVPlayback component, the actual component and libraries associated with it aren't loaded until a new FLVPlayback() instance is created. It will then load in the library and component into memory but you will never get that space back until the program / website is closed. That specific instance with the video inside of it will get garbage collected and release some memory as long as you remove listeners from it, take it off the stage, and set it to null.
Also, if you are doing individual videos, the VideoPlayer is much lighter weight, and cleans up nicer.
Thanks for the responses, the links to the other blog questions were helpful as well, I had read all of Grant Skinner's info on garbage collection too, but searching through those links and going back and re-reading what he had originally said about GC helped refresh the old noggin. In addition to nulling and re-instantiating that single FLVPlayback component, I also realized that I wasn't correctly unloading and destroying my Loader instances either, so I got them cleaned up and now the program is running much more efficiently. I would say the memory usage has improved by around 90% for the site.
#aib I will admit the single instance solution isn't elegant, but because flash just won't let go of those FLV files, I'm kind of stuck with it.
#grapefrukt I detest the flash components, they typically cause more grief than time saved, however in this case I had a lot of cue points and navigation stuff going on with the video files and the FLVPlayback component was the best solution I found. Of course I'm still fairly new to the ActionScript world so perhaps I over-looked something.
Unfortuantely, thats just the way flash handles it. Not particularly smart, but it works for most people.