Skip to main content
Inspiring
January 9, 2013
Question

Why isn't the AS3 garbage collector picking this up?

  • January 9, 2013
  • 1 reply
  • 4062 views

I started running into serious issues with the garbage collector partially picking this up, but still leaving most of the object up and running in the background without a reference:

m_win = new MyWindow(arr);
m_win
.open();
m_win
.addEventListener(Event.CLOSE, onClose);

.
.
.

private function onClose(pEvent:Event😞void
{
    m_win
.removeEventListener(Event.CLOSE, onClose);
    m_win
.close();
    m_win
= null;
   
// RAM usage for m_win is only reduced about 20-40%.  I can see the garbage
   
// collector has run as a result of that reduction, but the other 60-80% are
   
// a serious problem.
}


That's the only event listener I have added to m_win, and that's the only reference my code has to m_win.  MyWindow is basically a standalone AIR project (although it's nested in a different class than its own Main class to adapt it to work for this scenario; otherwise the same). MyWindow has NetConnections, NetStreams, and such that were kept live after the garbage collector would run.

So one of the first things I tried was to go in and disconnect its NetConnections and NetStreams.  But that didn't work.  Then I came across these blogs:

http://tomgabob.blogspot.com/2009/11/as3-memory-management.html

I found the link for that in another blog from another guy who had trouble with the same thing:  Supposedly if AS3's garbage collector finds an "island" that has reached a critical mass (in my experience, maybe 30 MB?), it just refuses to do anything with it.  So I went with this guy's recommendation and at least attempted to null out every reference, remove every event listener, call removeAllElements() and/or removeChildren() where necessary, and call "destructor" functions manually all throughout MyWindow, the sole exception being the Main class that isn't really used for m_win.

It didn't work, unless I messed up.  But even if I left a couple of stones unturned, it should have still broken up the island more than enough for it to work.  I've been researching other causes and work-arounds for this problem and have tried other things (such as manually telling the garbage collector to run), but nothing's cleaning the mess up properly.  The only thing that has worked has been to disconnect the NetConnection/NetStream stuff on the way out, but a good 25-30 MB is remaining uncollected.

How can this be fixed?  Thanks!

This topic has been closed for replies.

1 reply

Inspiring
January 9, 2013

Nulling your objects will not cause a sweep of your memory.

But there is a way to force garbage collection for testing purposes (found here)

To force an immediate GC mark/sweep, all you have to do is call connect() on two LocalConnections with the same name. This will throw an error, so you’ll have to wrap it in a try/catch block.

try { new LocalConnection().connect('foo'); new LocalConnection().connect('foo'); } catch (e:*) {} // the GC will perform a full mark/sweep on the second call.
Inspiring
January 9, 2013

The garbage collector runs, at least from what I've seen, but it only collects part of m_win.  One thing I've started to wonder about, but am kind of reluctant to go through the trouble of trying it without some sort of confirmation, is if it would help to try to give the garbage collector time to run at several points along the way, so as to feed it small "packets" from m_win to clean up separately.

Inspiring
January 9, 2013

Did you by chance read the last "official" article from Adobe about garbage collection, it goes into detail about how Flash 11/AIR 3?

http://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/garbage-collection.html

From what I understand it`s an overinterpretation to conclude Memory is freed-> Garbage collector ran.

There is also no mention of "islands" that would be too big to be marked for garbage collection.

I read the article you mentioned, and I can´t see how you take this sentence

there seems to be a limit on just how big an orphaned group of objects can be before the GC just gives up and assumes the whole group is still being used

as a proof, that there is sth. as an island-bug, its at best a vague assumption

That`s why I advised you to try to force garbage collection to make sure.