I am developing an AIR application using FlexBuilder (FlashBuilder) 4.0.1 (Standard) in an Eclipse plugin environment, on the Windows 7 64-bit platform.
My application is intended to run full-screen, on a touchscreen device, as an application for small children (pre-k).
The general operation is to present a series of scenarios, one by one, from a collection of separately developed swf files. (each swf file is a scenario). The child responds to the swf file, the swf file sends an event to the player, which performs an unloadAndStop() on the Loader object that loaded the swf. Then the next swf is loaded.
The problem we are seeing is that each swf file adds about 15-25 MB to the Workingset Private allocation of the AIR application (or the ADL.EXE runtime). Very little of this RAM is returned. After about 140 of these scenarios, the AIR runtime consumes about 1.6 GB of RAM. This, in itself, is not the problem - we could buy more RAM.
The problem is that the Loader crashes here, and takes the whole AIR runtime with it.
We also have a few "special purpose" swf files which are basically just wrappers around a s:VideoPlayer control, that plays a bindable file - .flv video, and the complete event fires the event that tells the AIR player to unloadAndStop the swf.
Since the video player took no manual intervention to test, I built a set of these to simulate a high load, and found that:
The .flv files are opened, but they are never closed. Since the s:VideoPlayer control is an MXML construct, there is no explicit way I can see to tell it to close the dang file when it's done. (it's not documented, anyway).
At exactly 32 video-swf items, the videos will continue to play, but there is no more audio.
At exactly 73 video-swf items, (seemingly regardless of the SIZE of the .flv file I select), the 73rd item crashes the Loader (and AIR player).
I supply unloadAndStop() with the (true) parameter. I follow it with a System.gc().
I explicitly remove ALL of my listeners. (in the AIR player application - I assume no control over items within the swf items that I am playing, since we assume we eventually may end up playing 3rd-party developed items; so we rely only on the return of a completion event, and a data structure).
I explicitly close() ALL of my audio streams. (at the AIR player level - not in the swfs.)
I explicitly stop() ALL of my timers.
My loader is instantiated in an element called "myLoaderContainer" - and after I receive my completion event, I do a myLoaderContainer.removeAllElements();
I have tried both the System.gc() call and the "unsupported" LocalConnection().connect('foo') call. both of these have zero effect. (in other words, I think there is probably no garbage to collect).
Still, I find it strange that nowhere, is it written, any kind of hint about how often garbage collection will do it's thing, and having graphed the flash.system.System.privateMemory; usage against all of my functions, and narrowed it down to my loader, and seeing that this allocation is never reclaimed, even on loader.unloadAndStop(true); - I wonder exactly what is the (true) parameter for, in that method?
I don't know what else I am supposed to do to force my Loader to *actually* unloadAndStop().
One would think that unloadAndStop() would not mean: "cease all functioning, but continue to occupy memory until the parent application chokes on it's own heap."