Jump to content
GreenSock

riawolf

[Bug] XMLLoader.parseLoaders function causes memory leak

Recommended Posts

in parseLoaders function there is a statement

for each (node in xml.children()) {
     parseLoaders(node, queue, toLoad);
}

this causes the XML object to be fully cloned, as node.parent() has access to parent node in XML, therefore every node and every sub node has access to the full XML tree, however it is not the same object but rather clones of it. In my application, this caused to have 522 XML objects created during runtime and total memory amount used was 42MB

 

the quick solution is to turn the node object into string and parse it again as XML, this reduced the memory amount drastically down to under 1MB

for each (node in xml.children()) {
parseLoaders(new XML(node.toXMLString()), queue, toLoad);
}

Link to comment
Share on other sites

Hmmm...I'm a little confused because it doesn't seem like doing a "for...each" loop of the children() creates clones of the entire XML tree - I check the parent() of each sibling to see if they're equal and Flash says they are. Clones would be unique in terms of instances. See what I mean? If they're pointing to the same object in memory, that shouldn't take up exponentially more space (at least that's my understanding). The only hesitation I have about implementing the tweak you suggested is that it does indeed lose all the parent/ancestor data. I realize it's probably rare, but if someone wants to check the rawXML property and go up the chain, they wouldn't be able to. So I'm trying to figure out exactly what's going on in your example. Can you please post a very simple FLA and XML file that clearly demonstrates the issue? That'd be super helpful for me in terms of troubleshooting.

Link to comment
Share on other sites

Try profiling this code, i know its a very specific set of conditions, yet it illustrates the problem

package 
{
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.setTimeout;

public class Main extends Sprite 
{
	private var _array:Array;
	private var _xml:XML;

	public function Main():void 
	{
		if (stage) init();
		else addEventListener(Event.ADDED_TO_STAGE, init);
	}

	private function init(e:Event = null):void 
	{
		removeEventListener(Event.ADDED_TO_STAGE, init);
		setTimeout(test,5000);
	}
	public function test():void {
		var xmlString:String = '';
		var nodeString:String = '';
		for (var i:int = 0; i < 50; i++) {
			xmlString += nodeString;
			for (var j:int = 0; j < 50; j++) {
				xmlString += nodeString+'';
			}
			xmlString += '';
		}
		xmlString += '';
		_xml = new XML(xmlString);
		_array = [];
		for each(var node:XML in _xml..node) {
			//_array.push(node); // memory leak; Memory:180,691,640 during runtime
			_array.push(new XML(node.toXMLString())); // no memory leak; Memory:5,290,963 during runtime
		}
	}
}

}

 

Edit:

I used flashdevelop SWF Profiler, not the most reliable tool i must say, System.totalMemory and windows Task manager showed normal memory amounts for this example even though SWF Profiler went totally crazy on me. So i started to play around. After tweaking the iterators for a while, i started to notice that memory test results became weird, spikes of memory if the cycle is over ~5000 iterations in the for each segment of the code. Maybe if you try recursive processing like in XMLLoader you will be able to recreate more controlled results

Link to comment
Share on other sites

Yeah, I think there might be something funky with the profiler because I'm showing that the original code (mine) results in LESS memory usage in virtually all my tests which would make sense because it only has one XML tree in memory whereas the code you recommended would keep creating copies for each branch and sub-branch, etc. See what I mean?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×