Skip to main content
April 23, 2012
Question

Memory related crashes in Flex application

  • April 23, 2012
  • 1 reply
  • 11052 views

We have a relatively heavy flex application running in a browser.

The Flash verison is 11.2 and Flex SDK is 4.1. Starting a while back we started having two kind of crashes often:

1. the GCOD - a grey circle with white exclamation mark that means too much memory is being used, leading flash player to commit suicide to protect the browser.

2. the browser becomes inactive for a while and then crashes, or recovers (but most often crashes).

We know we have a lot of memory leaks, and in some cases the crash is justified by memory usage. But, in some cases we record crashes without a high memory usage. I cannot explain these crashes. But we also know that in some cases Flash anticipates a large memory allocation and crashes immediately: this is the cases where, for instance you try to assign a negative value to the length attribute of a vector (i suspect the vector attempts allocation of the length size after an unsafe type convertion into a uint - resulting in a huge vector that cannot be held in memory). I have extensively searched our code for such access to the length attribute of Vector and could not find any.

Our measurements, assuming they are correct, lead to think that we have two kinds of different causes: one is plain memory leaks which lead us to the crash, and the other is an unknown cause that probably leads the flash player to trigger the GCOD with no real reason.

I have two questions:

1. How can I programatically anticipate the CGOD? is there a calculation I can apply to available memory metrics from within Flex applications so that the user can be warned to save all data before the crash in case the application leaks slowly?

2. What other possible bugs or mechanisms can trigger the GCOD without good reason? Since the negative length bug is not the cause in my case, maybe there are other usages that may lead to abrupt and inadvertent memory allocation?

The crashes are very frequent... Any help will be most welcome!

Ron

This topic has been closed for replies.

1 reply

drkstr_1
Inspiring
April 23, 2012

Have you used the profiler in Flash Builder at all?

It is impossible (for me at least) to anticipate all possible bottlenecks ahead of time. I always use the profiler to identify and fix these issues, and as a result, I do not experience any memory related bugs in my apps. I can't imagine building a large scale application without the use of a profiler.

If you are having trouble using the profiler to identify your bottlenecks, post back and I would be happy to give some suggestions.

Cheers!

April 24, 2012

Thanks. I did mean to ask if we can anticipate the crash in runtime - that is - to detect the high consumption and alert the user just before so she can save her data.

Also, this does not address the second issue - we are receivine the GCOD even when memory is relatively low. this cannot be a result of a memory leak, so a profiler probably will not help here.

That said - We are trying to make use of the profiler but have had extremely bad experience with it. First, it crashes more often than not. this is something we're working on to resolve - even when profiling an empty project with close to no code at all in it - we still crash when trying to navigate the memory allocation stack and reference chains.

Second, our application is way too large to be analyzed as is - I assume the best way to profile it is to cut it up into pieces - and that will also take some time. Lastly, we have had some success with the profiler in the past - but most of the time I just don't know how to use it.. I have read about different techniques, but most of the time I cannot find anything wrong with my classes or code. the main bulk of memory is hidden in classes of Function and BitmapData

Function - could indicate abuse of Binding or event listeners, and the BitmapData - could indicate a leak of styles or background images in containers. I could not find a way to effectively use the Profiler to identify the source of these leaks. and the fact that it's usually not working at all is discouraging. Any tips or suggestions will be greatly appreciated.

Let's start by saying that the application consumes too much memory. much more than it should. once we finish loading all code the application typically weighs about 400MB, which can jump up to 1GB without loading too much media (just some graphics occasionally) - as measured by task manager (including the browser and plugin)

There are many "best practices" I've read about that are intended to help cope with memory cleanups - implementing IDistroyable to remove event listeners, renferences, styles, images and URLLoaders - numerous advice and warnings regarding ItemRenderers etc..  I've been avoiding these advice since it seems unreasonable that i should have so much code that does basically nothing except what is expected from the framework. dealing with these cleanups should be transparent and done by the framework/VM. it was my hope that the framework will just mature to handle these issues. I just keep the links and references in my code as simple and straightforward as possible hoping this should be enough - As I would in Java.

Another issue is the depth of our UI tree. i was hoping it affects only CPU in event propagation and size calculations - but now I start suspecting that it also has memory implications (perhaps each container keeps BitmapData even though the bitmap cache is set to false by default?...).

Any thoughts or tips would be appreciated. But I stress - even if we clear all memory leaks and reduce consumption - it appears that the GCOD appears sometimes when memory use is low..

Thanks!..

Adobe Employee
April 24, 2012

You can try using System.totalMemory to anticipate a crash. It won’t reflect the memory shown by the task manager, but it will probably be proportional.

That said, there is usually a price to be paid for not employing best practices. If the profiler is barfing, that generally implies that you have simply created too many objects. A well written large application is modular and doesn’t create things until just before it is needed. The modules can be individually tested or at minimum, instantiated without instantiating every other module. And a modular app is usually more efficient to write and maintain: you don’t have to compile the whole thing for every change and different developers can work on different modules with fewer collisions. It is probably worth it for you to refactor your app now. Then the Profiler can help you find the other remaining problems.

There is a “tutorial” on the Flex 3 profiler on my blog. I haven’t updated it for Flex 4, but the principal is roughly the same.

Due to the nature of Flash Player memory management, it is often better to use object pools instead of creating and destroying lots of objects.

There are some questionable recommendations on how to manage memory better, but fundamentally, the issue is whether there are strong references to objects from the “GCRoots”. It is probably worth your time getting a better understanding of that so you don’t waste time nulling out references that don’t matter.

I’m sure there might be a bug or two involving memory leaks in the framework, but for the most part, the framework uses weak references correctly and does not leak memory despite what rumors may say. But it is easy to use the framework in a way that causes your code to get stuck and that’s why understanding how the reference chain from GCRoots work is important to understanding what code you do need to clean up.

The depth of the tree for most people doesn’t matter, but flatter is better. If you are getting out past 30 levels, then that is likely to be a drag on performance.

The most common way to crash the player besides consuming too much memory is to overflow the stack. Sometimes you will get a stack overflow error, but quite often, the player disappears without any notification. There is no control over maximum stack size and available stack can vary by player/browser. There is no way to know how much available stack space there is. I’ve only seen the stack overflow when I have a bug: I have a function that eventually calls back into itself (i.e. Infinite recursion). I’ve seen a few folks claim that they overflow in some complex sequence of calls that does have a cap. That is certainly possible, and code that walks a deep and complex display object tree is going to be more prone to that condition.

If an empty app crashes the profiler, make sure you restart Flash Builder before starting the profiler. If you are almost out of heap in Flash Builder the profiler is more likely to fail.

--

Alex Harui

Flex SDK Team

Adobe Systems, Inc.

http://blogs.adobe.com/aharui