+2  A: 

there is a trick to force the garbage collector

 try {
    new LocalConnection().connect('foo');
    new LocalConnection().connect('foo');
 } catch (e:*) {}
 // the GC will perform a full mark/sweep on the second call.

full article why this works

The new flash player has a static gc() method in the flash.system.System class. But this only works in the debug version

Toad
That did make it peak at 50MB, which is good. However, it really is a trick and seems to be an unintentional hack aswell. Quote from that link: "Again, this should only be used as a development aid. It should never be used in production code!" - I hope there are better solutions.
Tom
since flash is always maintained at the server and downloaded every time someone plays the game, why not stick with it, until it is proven not to work anymore or a better solution presents itself.
Toad
I think I will have to, unless other solutions exist. I shall wait for such a solution for a few days first. Yours will be accepted if not.
Tom
Hopefully someone will also be able to answer the question whether flash runs the garbage collector less often when you have more memory.
Tom
"..whether flash runs the garbage collector less often when you have more memory" - I know for certain that this is true in some cases (i.e. for some versions of the FP, on some OSs) - but I don't think anyone can tell you if it's true in all cases. See my answer for a few more details.
fenomas
+4  A: 

GC is a heavy operation so the Flash Player wouldn't perform it very often. If you have already make sure the BitmapData are able to be GC, let it be. FP will find the right time to GC.

It is really not recommended to manually control or try to control GC as you can never test the performance result of your own GC method on every CPU/RAM combination (and the results can be VERY different).


Update:

BTW, you may try out object pooling, which will:

  • Increase minimum RAM usage
  • Reduce the peak of RAM usage
  • Reduce GC frequency (increase performance as a result)

For more info and open source classes on object pooling, see here and there.

Andy Li
so it won't peak to 600 MB for other computers with less RAM?
Tom
It won't. Flash Player should know how much RAM it can get.
Andy Li
+1 for object pooling
HanClinto
+1  A: 

Don't worry about memory consumption. All those graphics will eat a lot of space regardless of how small the actual files are, they will be decompressed as you load them.

That means a 500x500 image in 32bits will take up 500x500x32 = 7.6mb's of memory. So yes, you will go through alot of memory.

The thing is that the person(s) who wrote the garbage collector and memory management are smarter than us. They know more about the flash player intricacies than we do, so just trust their better judgement.

Flash will naturally use as much memory as it can, it's what memory is for after all, it's not very much use if it's free all the time. So having 8GB of ram will make the GC run less often.

grapefrukt
eating up too much memory is never a good thing. It'll force other things to be swapped out earlier causing an unresponsive system
Toad
+4  A: 

I can suggest a few points not covered in other answers.

Regarding GCs: The precise triggers for what causes a GC are not (I believe) publicly published, but I do know that in some environments they occur naturally on a timer (if not triggered otherwise), and trigger when Flash's memory usage exceeds a certain percentage of the total memory available to it. Since you mention in comments that your overall memory usage doesn't go too high if you force GCs, then my first answer would be that you should stop worrying about memory usage until you find evidence that it is causing problems in this or that environment. Generally speaking Flash will avoid GCs if it thinks there is plenty of memory left, for performance, so if you see usage climbing but it's not affecting system performance, then attempting to "fix" that sounds suspiciously like premature optimization - your time would probably be better spent elsewhere.

Regarding your code: I only half-grok what you're doing here, but one thing I noticed is that you don't seem to call the dispose() method on any of your bitmapData objects. If it's not necessary ignore this, but if you are leaving any BMDs to be collected automatically, make sure you're disposing them.

Regarding architecture: I think you would see much lower memory usage overall (and possibly better performance) if you try a "one large bitmap" approach to this problem. That is, you keep one big (screen-sized) bitmap, and each frame you blank it out and use copyPixels() to copy in whatever decals (overlays) need to be in whatever positions. This can be faster than using displayObjects (like sprites) for your game objects, particularly when they are bitmaps originally, and don't need to be rotated, etc (which seems to apply to your case).

Compare with this question about the performance of using display objects vs. using a bitmap framebuffer. The asker ultimately found using a framebuffer was faster, and as an added bonus it ought to have much more predictable memory usage, since you won't be creating and destroying bitmaps or display objects. (All you create and destroy is the data you use to track where your decals are.)

fenomas
Thanks. About dispose, I tried using it, but the memory usage remained exactly the same. I thus didn't see the need and removed it again.
Tom