Tuesday, September 04, 2007

Garbage Collection

written by Marcel Panse

I'm working on an AIR application that has to load up a lot of pictures from a users system. I have to be able to load about 120 photos (of 3MB each), open them, resize it and save it in memory and cache a resized photo to disk. So i created a manager which has an internal queueing system which loads the photos one by one and doing the operations before continueing on to the next photo. The most processor time goes into loading the photos from disk into memory, which is a asynchronous job, so the GUI has plenty of time to update and keep track with a simple loading bar.

Now the weird stuff, the calls to load the next photo uses 'Application.application.callLater(loadPhoto)', on a Windows machine this is no problem at all, and it loads 120photos easily (i've tested it with up to 500). Now if you change that sencentence to 'setTimeOut(loadPhoto, 500)', then it suddenly stops working. It loads up to 70photos and then sais 'Invalid bitmapdata'. This is probebly because the garbage collector is too slow and can't free the memory intime, resulting in memory allocation errors.
When i'm running the same thing on a MacBook Pro (which is faster then my window laptop, and has twice the RAM), then suddenly both scenarios don't work and i can only load up to 17 photos. RAM Climbing very fast up to 500megs and crashes...

Now thats sucks big time!

Then i came across the web and found a garbage collection hack, i didn't feel like that was going to be the solution but gave it a try anyway and the miracle happend and everything runs like a charm, no problems at all on windows or the mac.

The hack is as follows:


private function gcHack():void
{
// unsupported hack that seems to force a full GC
try
{
var lc1:LocalConnection = new LocalConnection();
var lc2:LocalConnection = new LocalConnection();

lc1.connect('name');
lc2.connect('name');
}
catch (e:Error)
{
}
}


This forces the garbage collector to do a full garbage collection.
This makes me wonder, why isn't there a feature in flex that does exactly do this?

1 comment:

Kevin Richard said...

One would think that Adobe would have a GC object that you could instantiate and run like:

var gc:GarbageCollection = new GarbageCollection();
gc.clean();

Until that exists the hack that you found will have to do. Glad you found something that worked for your situation, Lord knows we have all had odd things like that show up and some even more obscure workaround (read that as a hack) that fixes the situation.

Remember, the internet is a series of hacks that somehow work together. While you were writing about an AIR project, it is using a web-based technology as it's core.