Copy link to clipboard
Copied
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!
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
I don't take what that other guy was saying as proof, but I have noticed a very serious issue with there being a 99% chance the garbage collector isn't working in my project, attempts to just make it hurry up and run are part of reason I think it's not working (although I thank you for your response earlier), and multiple people have supposedly been able to use that technique and near-assumption to their benefit in clearing out memory. So I was going to at least try it out.
Given Adobe's statements:
"GCRoots are never garbage collected."
and:
"The MMgc is considered a conservative collector for mark/sweep. The MMgc can't tell if certain values in memory are object pointers (memory addresses) or a numeric value. In order to prevent accidentally collecting objects the values may point to, the MMgc assumes that every value could be a pointer. Therefore, some objects that are not really being pointed to will never be collected and will be considered a memory leak. Although you want to minimize memory leaks to optimize performance, the occasional leaks that result from conservative GC tend to be random, not to grow over time, and have much less of an impact on an application's performance than leaks caused by developers."
I can see sort of a link between that and the "big island" theory at this point though - assuming the theory is correct, which I'm not. Adobe's pretty much admitting at this point, in at least the second statement, that there are at least benign issues with orphans getting skipped over. They act like it's no big deal, but to just leave it like that and pretend it's nothing is probably mostly just typical Adobe sloppiness. What if one of those rare missed orphans that they mentioned has a large, fully-active object hierarchy within it? If you can't prevent the memory leak there completely, I could definitely see how going through and doing things like nulling out references all throughout that hierarchy before you lose your reference would generally do a lot to minimize the amount of memory leaked as a result.
My thinking is that the garbage collector would generally still be able to get rid of most of everything within that island, just not the island itself. Also what some of these people and I were seeing was probably some of "less benign" manifestations of what Adobe was admitting to.
Copy link to clipboard
Copied
Howitzer21 I think I've run into a similar problem and it's been three years since you mentioned this issue, so maybe you came up with a solution?
Copy link to clipboard
Copied
using localconnection to force gc (first published by g skinner) no longer worked by the time flash cs3 was released.
to force gc while testing, you can use:
System.gc();
to track what's in memory, you can use adobe scout: http://www.adobe.com/devnet/flashruntimes/articles/adobe-scout-getting-started.html
or, a little easier (but far less debugging information), a memory tracker class: http://www.adobe.com/devnet/flash/articles/optimizing-flash-performance.html
Find more inspiration, events, and resources on the new Adobe Community
Explore Now