Allowing XML to be interpreted causes a 30 MB Memory Leak
If you are adept with E4X and XML in AS3, take a look at this CRAZINESS.
I have a 420 KB XML. Fairly large, yes. Its structure is fairly simple:
<Nodes>
<Node ID="1">
<Element Name="A" />
<Element Name="B" />
</Node>
</Nodes>
I have between 2 to 10 Elements in a Node and about 50 Nodes in total.
I am storing all the individual "Element" collections into a Dictionary, where the Key is the value of the Node ID attribute. Don't ask why I did it like this, okay? I had a good reason for it.
All right, so we got a Dictionary with about 50 keys, each of them containing values which are XMLLists of 2 to 10 Elements.
So, the big XML is split into more XMLLists and stored into the Dictionary like this:
for each (var obj: XML 开发者_如何学编程in objects)
_SomeDictionary[int(obj.@ID)] = obj.Element;
Now here comes the weird part:
- Run Application.
- Initialize some objects using 10 of the 50 Dictionary Values.
- Memory Consumption: 36 MB.
- Run Application.
- Initialize objects using ALL 50 of the Dictionary's Values.
- Memory Consumption: 47 MB.
But... if I do it like this:
for each (var obj: XML in objects)
_SomeDictionary[int(obj.@ID)] = String(obj.Element);
I get this:
- Run Application.
- Initialize objects using ALL 50 of the Dictionary's Values, and prior to initialization, cast the Dictionary's Value back to XMLList.
- Memory Consumption: 16 MB.
So I shaved 30 MB of memory just by casting the XMLList to a String. Why does this happen? Eventually, inside the Initialization function which processes the Dictionary's Value, an XML List will ALWAYS be created.
Second question: when NOT casting to String, WHY does the memory increase when I process the Dictionary's Values??? They're all XML Lists already! Why does the memory only grow from 36 MB to 47 MB when I actually pull out the XML List from the Dictionary and go through it with a function which initializes some objects based on it?
P.S.: The function does not cause memory leaks: I already proved that I only get 16 MB when I am using the SAME function but instead of giving it an XML List pulled directly from the Dictionary, I give it an XML List cast out of a String which is pulled from the Dictionary.
This might explain it.
in Flash the master string is referenced even if you just use a fragment:
var str:String = "ABCDEFGHIJKLMNOPQRSTUV".substr(0,2);
trace(str + " has master string " + flash.sampler.getMasterString(str));
// output: AB has master string ABCDEFGHIJKLMNOPQRSTUV
精彩评论