On iOS, but not web or Android, I'm seeing mysterious hidden Strings being allocated on code like the following:
// Set up variables for test:
var dict:Dictionary = new Dictionary();
var key:String = "the_key";
var obj:Object = {};
// Add to dict a Vector of Objects, initialized from the array [obj]
dict[key] = new <Object>[obj];
// OFFENDING CODE:
// According to Scout, this assignment allocates 6 strings (!?) behind the scenes on iOS.
var vec:Vector.<Object> = dict[key];
I've set up a test case where a function that does an assignment like that (and essentially nothing else) gets called many times, and Scout shows it allocating 6 Strings for every assignment.
It appears to allocate these Strings if the value of dict[key] is a Vector.< Object>, Vector.<Function>, or Vector.<user-defined class>, but *doesn't* allocate if dict[key] is a Vector.<int> or an Array.
(I've also discovered it happens if dict is an Object rather than a Dictionary.)
Again, I see this on iOS, but not on web or Android.
We use that pattern, String-keyed Dictionary of Vector.<*>, throughout our large code base, and those extra allocations are causing an unacceptable amount of GC activity, especially given that this is a simple assignment of a property in a dictionary to a variable of the same type.
The Starling framework also uses this pattern in its EventDispatcher class, which is where I first noticed the problem of thousands of Strings being allocated by EventDispatcher::hasEventListener(), which does nothing that should allocate.
I added a bug (#4115729) on Bugbase with the exact test code attached to illustrate the problem: