It is so strange that I always got a lot of memory leaks when using a plenty of Image object. The following are common usage from me or others:
var imgDummy = new Image();
imgDummy.source = "whatever.png"
this.addChild(imgDummy);
After the above codes, an image is created and put in the container.
while removing image from the container, we always use:
this.removeChild(imgDummy);
But it leaks.
This is so strange. While using the same scenario in other programming language like Java, C#, this problem won't be there. But it is in Flex.
So, I create a project for testing this symptom. I load an image 300 times and put them in a container:
private function createObjects():void
{
var imgTest:Image;
for(var i:int=0;i<300;i++)
{
imgTest = new Image();
imgTest.source = "loading.png";
m_Container.addChild(imgTest);
}
imgTest = null;
}
where m_Container is a Canvas object.
As to freeing code, I wrote three kind:
1. free image by removeAllChildren
private function freeObjects1():void
{
m_Container.removeAllChildren();
}
2. free image by removeChild one by one
private function freeObjects2():void
{
var imgTest:Image;
while(m_Container.getChildren().length > 0)
{
imgTest = m_Container.getChildAt(0) as Image;
m_Container.removeChild(imgTest);
}
imgTest = null;
}
3. free image by removeChild and set the source of image to empty string
private function freeObjects3():void
{
var imgTest:Image;
while(m_Container.getChildren().length > 0)
{
imgTest = m_Container.getChildAt(0) as Image;
imgTest.source = "";
m_Container.removeChild(imgTest);
}
imgTest = null;
}
4. free image by removeAllChild() and set the source of image to empty string
private function freeObjects4():void
{
var imgTest:Image;
for(var i:int;i
{
imgTest = m_Container.getChildAt(i) as Image;
imgTest.source = "";
}
imgTest = null;
m_Container.removeAllChildren();
}
This is the profiling image of each freeing method:
Method 1:
This is a strange image that the first and second "V style" sharp occurred while creating images after free them. But after these two "V style" sharp, it doesn't free any memory.
Method 2:
Basically, I press for times create and free, the memory raises a little. In this method, Flex recycles the created objects, but it doesn't free any memory while freeing them.
Method 3:
This method works. The key point is imgTest.source = "". This expression makes the SWFLoader inside Image unload everything.
Method 4
This method works, too. There is no difference between method 3 at memory freeing.
The sample program is
here.
Be careful, I the profiling is running at "debug" mode. But app always running at release mode. The above methods seems useless at release mode. This may be caused by System.gc() is only workable at debug mode and garbage collection is done automatically by Flash VM at release mode. So, there is no way to force gc at release mode.
I had googled this issue for a few days, it seems there is no solution for this problem. But at least, in the debug mode, we can make sure the memory doesn't leak.
some references about memory leaks: