Hi,

I'm working on an AIR application that has to load a lot of pictures
from a users harddrive. I have to be able to load about 120 photos (of
3MB each), open them, resize it, save it in memory and cache a resized
photo to disk. So i created a manager which has an internal queueing
system that 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 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 probably
because the garbage collector is too slow and can't free the memory in
time, resulting in memory allocation errors. 
When i'm running the same thing on a MacBook Pro (which is faster then
my windows laptop, and has twice the amount of RAM), then suddenly
both scenarios don't work and i can only load up to 17 photos. The RAM
Climbing very fast up to 500megs and crashes...

The solution would be to force the garbage collector to free the
memory between each load, but there is as far as i know no such
functionality in flex. I have found a little hack that forces the
garbage collection to free the memory by creating multiple
LocalConnections with the same  name (and catching the exception it
throws). Using that hack everything works fine on both the windows
laptop and the MacBook. 

This is the garbage collection hack:

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 is offcourse not the solution we'd like to go into production
with. Is there a better solution, what is the 'official' way to do
such things?

Reply via email to