Memory leak in Flex Charts - apache-flex

I have created a UI that displays 3-4 charts in the UI.
I notice the following
As soon as these charts load up the IE memory shoots up to around 400 Mb which is understandable because some of these charts are like tables displaying upto a thousand rows.
I notice the more I refresh these charts the more IE memory increases.
From a simple walkthrough of the code multiple times, I couldn't find any leaks or any data structures who size was increasing. I am using Flex builder 2. I have a few questions:
When does Flash free the memory ?
Can I IE return that memory to the
OS ?
Is there a known memory leak in
Flash ?
What are the tools that could
possible help me ?
Does any programming best
practise like making unused
Objects explicitly as null, help
?
thank you very much.
I have one more question, it seems that the IE doesn't release any memory at all unless it is minimised ?

1) This article will explain everything about Garbage Collection (which is how managed languages take care of memory management). Basically you have no control of when it runs(there is a hack to force it but you shouldn't be using it)
http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html
and this
http://blog.flexmonkeypatches.com/2007/03/28/flash-player-memory-management-and-garbage-collection-redux-2/
2) There shouldn't be a leak as long as you are ensuring that objects no longer needed are able to be garbage collected. That being said I am not familiar with Flex and perhaps there is a bug in the framework??? EDIT: There seems to be a lot of people who have problems with flex+ie and memory leaks.
3) System.totalMemory will at least help you see how much memory you are using. EDIT:Forgot to mention if you upgrade to Flex Builder 3 it comes with memory profiler tools
4) Yes, if you no longer need something setting it to null is good practise. Don't forget to remove any event listeners and make use of weak listeners where you can. If there is still a reference to something then it won't be marked for the garbage collector.

Related

Removing Flex DisplayObjects from view AND memory pool

I have an issue with a Flex application, one that I didn't build, so I can provide all my findings but sorry for any lack of clarity.
There is a Flex app with 7 main views. And there is a memory issue when navigating between views.
All these views were in a ViewStack, but due to some involving 3D objects I assumed it was too much to have it all in the display list. I'm now clearing all children from the stack and adding/removing them when needed. This gave a small performance increase, but still becomes unresponsive with use. The strange thing is, with this and the original method, the CPU climbs with use but eventually levels out somewhere. Now I'm creating new instances of each screen when they are navigated to and setting the previous variable to null. Now it looks like CPU is spiking when the view is created, but leveling out to something much much lower than it was. This felt like progress, but now the available memory keeps climbing where it wasn't before....
My understanding was calling remove child or remove all children would mark the object for deletion when the garbage collector next ran. I can't see any other references to the instance. My code is along the lines of
this.parentApplication.viewstack.removeAllChildren();
this.parentApplication.viewstack.addChild(new HomeScreen);
I have a function for each button to add a new instance like the above.
The only thing I can see and feel silly asking but need confirmation, is each view extends a class called "Screen", this class contains a singleton reference to some core components
this.model = PancakeApplication.instance.model;
this.meaModel = MeaApplication.instance.meaModel;
this.meaModel.addEventListener(ScreenChangeEvent.SCREEN_CHANGE, electedScreenChangeHandler);
Would this trick the garbage collector into thinking it was still needed?
General advice on clearing Objects from the memory pool would awesome!!! I've never needed to analyze the Flash Player in such depth.
SOLVED: I think it's an error with sound drivers, removing all sound and shes purring like a kitten. Works on my machine fine with windows XP, but not on the touch pad the application is crashing on with windows 7 (unsure of the drivers looking into them now).
UPDATE: Now I'm thinking its not the drivers, tried 3 different versions, all with no improvement. I did discover the sound was fading in and out with the TweenLite lib. Doesn't look like there are any memory leaks in TweenLite as it works fine on other machines. Just the use of volumeEasingFunction seems to consume increasing amounts of CPU until it freaks out. It is crappy hardware running windows 7, which doesn't help.
The first thing that comes to mind is you should be setting the use weak reference parameter to true in your event listener. It is the fifth parameter, so in your example:
this.meaModel.addEventListener(ScreenChangeEvent.SCREEN_CHANGE, electedScreenChangeHandler, false, 0, true);
Grant Skinner has a great 3 part series on AS3 Resource Management that would probably help you get a better idea of what to look for. You can find the details about weakly references listeners in part 3 or in a standalone article written before part 3 was posted.

Bitmapdata heavy usage - memory disaster (spark/FB4)

I've got a flex component which works pretty well but unfortunately turns into a
disaster once used in a datagroup item renderer of about 40-50 items.
Essentially it uses bitmapdata to take screenshot of a fully-rendered webpage in
mx:HTML (this version of webkit rocks btw, miles better than flex 3).
The code is pretty self-explanatory I think.
http://noben.org/show/PageGrabber.mxml
I've optimized it all I could, browsed, search for answers and already trimmed
it down a lot, I'm desparate to reduce the memory usage (about 600mb after 100
draw)
The Garbage collector has little effect.
Thanks!
Nic
You need to call BitmapData.dispose() when you're done with them, you can't just chuck them away and hope they get collected. Sometimes they will, but often not :'(
would the event listeners be holding on due to strong referance? Try removing listeners or using weak references. See if it helps
Do you ever dispose of smallBMD? You might want to make sure they aren't accumulating in memory, lingering around after use, since you create a new one each time the passoire_completeHandler is called, without disposing the previous one (as far as I can see).

AS3 large game performance degradation over time

I'm currently working on a very large Flash platformer game (hundreds of classes) and dealing with an issue where the game slowly grinds to a halt if you leave it on for long enough. I didn't write the game and so I'm only vaguely familiar with its internals. Some of the mysterious symptoms include,
The game will run fine for a determinate amount of time (on a given level) when all of a sudden it will exponentially start leaking memory.
The time it takes for the game to hit the point where it leaks exponentially is shorter when there's more sprites on the screen.
Even when nothing is being visibly rendered to the screen, the game slows down.
The game slows down faster with more frequent sprite collisions.
Completely disabling the collision code does slow down the degradation but doesn't prevent the game from eventually dropping frames.
Looking at the source and using Flex profiler, my prime suspects are,
There are many loitering objects, especially WeakMethodClosure, taking up large amounts of memory.
The program makes extremely extensive use of weak event listeners (dozens dispatched per frame).
BitmapData is being copied every time a new sprite is created. These are 50x50 pixel sprites that spawn at about 8 sprites per second.
I know it's next to impossible to tell me the problem without seeing the source, so I'm just looking for tidbits that might help me narrow this down. Has anybody experienced this evasive performance degradation in their own projects? What was the cause in your case?
I recently completed a optimization of an large project.
And I can give you some architectural advices:
Main principle – try do as little as possible function / events calls
Get rid off all but one
onEnterFrame / onInterval / onTimer cycles. Do everything you
need in one general event call.
You probably will need a lot of static arrays for storing processed object
references.
Do your graphics / render stuff also in one main loop
Try use big (probably prerendered) canvases instead of small sprites / bitmaps.
Usually it usable for backgrounds. But also working good for a smaller objects
(like trees, platforms, etc)
Rid off small bitmap resources, assemble it to one tile-sheet and draw your stuff
directly from it, through source–rect property
I hope its helps you!
Memory leaks – such headash.
P.S. Test your game in different browsers, IE – most leaking of all, sometimes it don`t clear memory every after refresh.
Avoid anonymous methods - change them into class level methods.
Use weak reference in addEventListener and/or make sure you remove all the listeners of an object before removing it with removeChild
Make sure you removeChild all the sprites instead of just letting them fly off the screen. Also, if possible, reuse the sprites instead of creating new ones.
You should consider object pooling if you have a lot of creation/destruction going on, especially with heavy objects like bitmapdata.
see Object Pool class
Sounds like you need to profile your application to see what is happening.
This thread had a couple of suggestions, but, ultimately, you will need to just put in code to help determine what is going on.
Profiling ActionScript-3 Code
You may want to see if you can just run some smaller parts over a period of time and see if you see a slowdown.
You may want to unit test your application, so you can run various parts rapidly, looking for memory leaks.
One framework is: http://asunit.org/, and another is: http://opensource.adobe.com/wiki/display/flexunit/
Unit testing is something I use a great deal for profiling, so you can test at the top level of your game, run it thousands of times, looking for problems, then run each part and see which has problems, and just work your way down. This is a manual process, but if the two ideas in the SO thread listed in the beginning don't help, this may be your best approach.
Are you using too much memory? Or is your cpu usage too high?
First determine if its a memory or processor limit you are hitting. It sounds like the later, seems like there are many objects doing stuff around ... likely those extra sprites aren't being freed well. Look for dependencies among objects / variables / anything in those events, make sure the sprites are removed, pay attention to any handlers of EnterFrame or recurring events.
It sounds far more likely that you are capping out on processor speed than memory. You have to try extra hard to memory cap a Flash application.
Fortunately there are a lot of easy things you can do to keep CPU down...
1) Stringently manage event listeners for everything, especially mouse listeners. Do you have $texas event listeners on all your sprite objects? That could be a problem.
2) Access arrays using int or uint instead of Number. This is huge, and this is one of those backwater Adobe tricks. Accessing array object with int and uint is way faster than Number and if you do a lot of iteration (and it sounds like you do) this could shave precious milliseconds off your frame execution.
3) In the same vein as #2, monitor your math operations and what types you are using for certain operations. The slowest thing you can do in math operations for AS3 is repetitive casting (feeding ints to a function that returns a Number), or performing basic operations like add and subtract on Number instead of int.
The great thing about having a wtfhuge program like this in Flash is that even a minor optimization change could have a major impact on performance. I once toyed with a raytrace engine in AS3 where I declared one extra variable and it killed my FPS from 30 to 23.
Flash has a rather infamous issue (many consider it a bug) that causes event listeners for timers and the ENTER_FRAME event to not get garbage collected, even if they were weakly referenced. So, even though it's good practice to use weakly referenced events, you should still remove all your event listeners when they are no longer needed.

Adobe Flex App page file usage going through the roof!

I have been working on an Adobe Flex application for some months now, and the application is meant to run 24/7 for days (weeks!) continuously. However, I'm now seeing that after a few days of running nonstop the computer it runs on tells me that the system is low on virtual memory and gives me an error about Page File usage. Once I close the Flex app, the Page File usage goes down from 1.9 GB to 100 MB (or less). It seems that its using up all this memory and not freeing it although I have been very careful in my app to not keep huge arrays.
The app does some graphing and draws a lot of shapes (to greate a 'gauge') and then gets rid of them by re-declaring that object as another 'gauge'.
Any idea why my page file usage is climbing so high?!
You most probably have eventListeners that are not being removed. They keep references to objects and prevent them from being garbage collected.
You can use the profiler in Flex Builder professional to see where your memory usage is going. Like another poster mentioned, event listeners are alot of times the culprits in cases like this, but more generally, just because you think you are getting rid (destroying or deleting) a variable, doesn't mean that it is really getting taken care of by the garbage collector. If any reference (like an event listener) still exists to that variable (or object) it will not be collected. The profiler will point out these things.
I've heard rumors that putting anything on the Stage will create memory leaks. In other words, you can be as careful as possible with your code, but you'll still leak memory. This has not been validated by Adobe, as far as I know. A good test might be to instantiate a Shape and a Sprite and a MovieClip, add them to the display list, and then let the app run overnight. Would love to hear the results if you do end up testing this.

Force Garbage Collection in AS3?

Is it possible to programmatically force a full garbage collection run in ActionScript 3.0?
Let's say I've created a bunch of Display objects with eventListeners and some of the DO's have been removed, some of the eventListeners have been triggered and removed etc... Is there a way to force garbage collection to run and collect everything that is available to be collected?
Yes, it's possible, but it is generally a bad idea. The GC should have a better idea of when is a good time to run than you should, and except for a very specific case, like you just used 500MB of memory and you need to get it back ASAP, you shouldn't call the GC yourself.
In Flash 10, there is a System.gc() method you can call (but please don't, see above) - keep in mind System.gc() only works in the debugging version of Flash player 10+.
In Flash 9, there is an unsupported way to force it via an odd LocalConnection command, but it may not work in all versions. See this post by Grant Skinner.
There is a new API for telling the GC that it might be a "relatively good moment" to collect.
See the Adobe API docs for
System.pauseForGCIfCollectionImminent
And also this Adobe blog post from shortly after the method was introduced in Player version 11
The method takes an "imminence" argument; basically, you feed in a low number (near 0.0) if you really want the collector to run, even if there has not been much activity (currently measured by bytes-allocated) since the last collection, and you feed in a large number (near 1.0) if you only want the collection pause to happen if we were already near the point where a collection would happen anyway.
The motivation here is for situations in e.g. games where you want to shift the point where GC's happen by a small amount, e.g. do the GC during a change of level in the game, rather than two seconds after the player started exploring the level.
One very important detail: This new API is supported by both the Release and the Debugger Flash Runtimes. This makes it superior to calling System.gc().
For all currently released versions, System.gc() only works in the debug version of the Flash player and ADL (the debug environment for AIR apps). Flash player 10 beta currently does work in all flavors.
I agree with Davr, it's a bad idea to do. The runtime will usually have a better idea than you do.
Plus, the specifics of how the garbage collector works is an implementation detail subject to change between flash player versions. So what works well today has no guarantee to work well in the future.
As others said: do not try to GC manually, there are hacks but it's not safe.
You should try recycling objects when you can - you'll save a lot of memory.
This can be applied for instance to BitmapDatas (clear and reuse), particles (remove from display and reuse).
I have a comment on those saying you should never do GC manually. I'm used to manual memory management in C++ and I prefer sharedptr a lot over GC, but anyway.
There is a specific case where I can't find another solution than do a GC. Please consider: I have a DataCache class, the way it work is it keeps result objects for certain method calls that send out updated events when refreshing/receiving data. The way the cache is refreshed is I just clean all results from it and send the event which causes any remaining listeners to re-request their data and listeners that went out of scope should not rerequest which cleans out not needed results. But apparently, if I can't force all listeners that still dangle waiting for GC to be cleaned up immediatly before sending out the "ask you data again" event, those dangling listeners will request data again unnecessarily. So since I can't removeEventListener because AS3 doesn't have destructors I can't see another easy solution than forcing a GC to make sure there's no dangling listeners anymore.
(Edit) On top of that I cannot use removeEventListener anyway for binding which were setup in mxml, for example (using my custom DataCacher class which handles remoteobj)
<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />
When the popup window containing this datagrid is closed, you would expect the bindings to be destroyed. Apparently they live on and on. Hmm, shouldn't flex destroy all bindings (meaning eventlisteners) from an object when it's being marked for GC because the last reference is deleted. That would kinda solve the problem for me.
At least that's why I think, I'm still a beginner in Flex so any thoughts would be appreciated.
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*){
trace("Forcing Garbage Collection :"+e.toString());
}
If you have to, calling the gargabe collector could be useful... so, you have to be carefull how and when you do it, but there is no doubt that there are times when is neccesary.
for example, if you have an app that is modular, when you change from one view to the other, all the deleted objects could represent a large amount of memory that should be available as faster as possible, you just need to have control of the variables and references you are disposing.
recycling doesn't really help. I used one loader that repeatedly loaded the same jpg every 500ms. task manager still reported a non stop increase in memory.
tried and proven solution here.
http://simplistika.com/as3-garbage-collection/

Resources