So I continued doing work on why flash objects weren't freed when they
had no refs in my code (see my previous post about the cameraVarsStore
not resetting its viewTransformDictionary). The next culprit I found
was the DrawPrimitiveStore. When a createDrawDisplayObject is called
it will either create a new one, or pop one out of _doStore if
possible to save the create step. When reset() is called on the
DrawPrimitiveStore the entire _doArray is stuffed into the _doStore
for reuse.
The problem is that it doesn't clear the references in each of these
DrawDisplayObjects to source, session, or displayobject before it
stuff it into the store. This means that every cached
DrawDisplayObject in _doStore is holding onto refs it shouldn't, and
keeping flash objects from being garbage collected. In our case,
large movieclips on MovieClipSprites were hanging around because of
refs in here.
Now if a DrawDisplayObject is pulled out and reused, the
source,session, and displayobject fields get set to new values and
this frees the old refs, but if the number of objects goes down,
you're left with objects in the cache that don't get reused and memory
that doesnt' get freed. I believe the right thing to do is to clear
the refs in the _doArray before stuffing it into the _doStore, like
this:
for (_object in _doDictionary) {
_session = _object as AbstractRenderSession;
if (_session.updated) {
_doArray = _doDictionary[_session] as Array;
var i:int;
for (i = 0; i < _doArray.length; i++)
{ // Clear any references so we can gc these if
needed
var dobj:DrawDisplayObject = _doArray[i] as
DrawDisplayObject;
dobj.source = null;
dobj.session = null;
dobj.displayobject = null;
}
_doStore = _doStore.concat(_doArray);
_doArray.length = 0;
}
}
I made these changes in my prviate build, and it seems to gc correctly
now. I'm not sure if there are any sideeffects I'm causing here that
I don't understand, so I'm chucking it for comment. Does this look
right?