Flex 3:Feature Introductions: Performance and Memory Profiling
From Adobe Labs
Table of contents <script type="text/javascript"></script> [hide] |
Introduction
One of the exciting new features of Flex Builder 3 Beta 1 is the Profiler. In this write-up, I'll be explaining how to get started with the Profiler and how to accomplish some common tasks. Along the way, I will also be pointing out some gotchas and bugs to watch out for.
Getting Started
To get started with profiling, look for the profiler button in the Flex Development perspective's toolbar:
Clicking on the profiler button , should launch the application using the default browser. Due to a profiling bug with the ActiveX Flash player, you will either want to use Firefox or the standalone Flash player for profiling. We hope to post a new ActiveX Flash Player soon after beta 1 is released to address this. See the <A HREF="#Player Launching">Player Launching</A> section for more info.
After launching, the Profiler will pause the application:
Then the Profiler will display a "Profiler Agent" configuration dialog:
You will have to raise the Flex Builder window to see it, though. We have an open bug to make Flex Builder flash in the taskbar or come to the front (See bug SDK-11142).
In the configuration dialog, you should see four check boxes. The first, "Enable Memory Profiling" will cause the Profiler Agent to collection information each time an object is created and garbage collected. This information is useful when trying to find potential memory leaks and when trying to find excessive object creation.
The second check box, "Enable Performance Profiling" will cause the Profiler Agent to collect a stack trace sample at regular intervals. These samples can be used to determine where the bulk of the execution time in your application is spent. Sampling allows you to profile without noticeably slowing down the application.
The third check box, "Enable Live Memory Data", instructs Flex Builder to display the "Live Objects" panel. This panel shows what classes have been instantiated, how many have been created, how many are in the heap, how much memory they have taken up and how much memory the active objects are taking up. In some cases the Flash Player is not reporting the correct size. This explains why a few classes have zero in the Memory columns.
The fourth check box, "Generate Object Allocation Stacktraces (WARNING: SLOW)", will cause the Profiler Agent to capture a stack trace each time a new object is created. Unfortunately, this is currently memory intensive, but it's an area where we plan to focus our attention for the next beta. For small applications is should be ok to enable this setting, but for larger applications, it will likely cause your machine to run out of memory. As a gauge, my computer has 1 Gig of RAM and I often run out of memory when enabling this while profiling the Flex Store sample application.
For now, we'll just leave the defaults and click "Resume".
Profile Panel
This panel shows each of the applications currently being profiled and the status, Running or Terminated. It's possible to analyze exiting memory and performance snapshots after the application has been terminated.
Here are the Profile panel's toolbar buttons and what they are used for:
Used to resume an application.
Used to suspend an application.
Used to terminate an application. This shuts down the standalone player, but currently does nothing with the browsers (See bug SDK-11141 and SDK-11044).
This forces a garbage collection. A garbage collection is automatically forced before each memory snapshot.
This takes a memory snapshot.
This finds potential memory leaks. Two memory snapshots must be selected for this button to be enabled.
This shows memory use by function.
This resets the starting point for the next performance snapshot.
This takes a performance snapshot.
Deletes the currently selected application or snapshot.
Displays the menu, which includes the Launch menu item.
Displays the launch dialog, which can be used to profile external applications. Look for this to be more prominent in the next beta.
Live Objects Panel
This panel shows the class name and package name of each object which has been instantiated since the application started up. The package name will be empty for top level classes, like HelloWorld, and built in classes, like String and Class. Also shown is the cumulative instances, currently live instances, cumulative memory use, and current memory use. As objects are garbage collected the number of instances and memory use should go down, but the cumulative instances and cumulative memory use should continue to go up.
You may be surprised by the number of Strings that an empty Flex application creates. First off, an empty Flex application is not really empty. Alot of infrastructure is created just by using the <mx:Application> tag. The good news is that you pay that infrastructure cost only once. Also, the number of Strings includes all the package names, class names, function names, variable names, and String values. In addition, all the file names needed for verbose stacktraces are included in this number. If you take a look at the Flex framework source code, you should quickly see how this adds up, even with an empty Flex Application. The good news is that the Flash Player handles it with ease.
Memory Snapshot Panel
To take a memory snapshot, select an application in the Profile panel:
Then click the memory snapshot button in the toolbar. After that you should see something like this:
After that, double click on the memory snapshot node. This should bring up a Memory Snapshot panel:
If you see a NullPointerException in the Console panel, restart the application and try taking another memory snapshot. We have this bug fixed, but the fix didn't make the beta 1 freeze (See bug SDK-11139).
Loitering Objects Panel
To use the "Loitering Objects" panel, you need to start by taking an initial memory snapshot, see "Memory Snapshot" panel. After that you will want perform some actions, which you suspect might be causing a memory leak, in the application. Next, you need to take another memory snapshot. Here is what that should look like:
Next select the two memory snapshots by selecting one memory snapshot, then hold down the Ctrl key and select the other memory snapshots:
Then click on the "Loitering Objects" button , which should have become enabled after selecting two memory snapshots. This should bring up the Loitering Objects panel:
Rows in the "Loitering Objects" panel represent potential memory leaks. It's likely that some of the objects, which were created between memory snapshots and which were not garbage collected, are expected. Any that aren't expected, are memory leaks. You'll have to investigate your application to determine which are unexpected.
Object References Panel
Doubling clicking on a row in "Loitering Objects" panel should bring up the "Object Referencs" panel:
Due to a bug, this panel often shows duplicates (See bug SDK-11025) and sometimes the back references are missing (See bug SDK-9421). This panel will work much better in the next beta. The "Allocation Trace" side panel will not show allocation traces unless they were enabled, see the "Configuration Dialog".
Allocation Trace Panel
Clicking on the allocation trace button brings up the Allocation Trace panel, which shows memory use by function:
This panel is useful in determining which functions use the most memory. These functions are the places to look if you want to reduce memory use or excessive object creation.
Note the "Generate Object Allocation Stacktraces (WARNING: SLOW)" check box must be checked for this panel to function. See <A HREF="#Getting Started">Getting Started</A>.
Performance Snapshot Panel
To take a performance snapshot, select an application in the Profile Panel:
Then click the memory snapshot button in the toolbar. After that you should see something like this:
After that, double click on the performance snapshot node. This should bring up a Performance Snapshot Panel:
There is a bug with package level functions, like trace() and flash.utils.describeType(), where the number of calls is always zero. This should be fixed for beta 2.
Method Statistics Panel
To open the Method Statistics Panel, double click on a row in the <A HREF="#Performance Snapshot Panel"/>Performance Snapshot Panel</A>:
You can drill down on a function by double clicking on a row in the Callers or Callees table:
Launch Dialog
The launch dialog can be used to profile applications outside Flex Builder. To open the Launch Dialog click on the menu icon and click on the Launch Dialog icon
. It should look like this:
To launch an application, select it and click the "Launch" button. Alternatively, click the "Don't launch the player/browser and accept one connection only" check box. Then open the application using a browser or the standalone Flash Player manually.
Player Launching
When profiling, the default for Flex Builder is to launch your application using the default browser:
If you default browser is "Internet Explorer", you will want to select "Firefox" for profiling with beta 1. Alternatively, you can explicitly specify a standalone player or browser using the Flex Player/Browser preferences:
FAQ
1. What are the bracketed functions, like [reap], [newclass], [mouseEvent], [enterFrameEvent], etc?
These are synthetic functions that the Flash Player inserts into stack traces to help explain what is going on when AS3 code is not being executed.
2. What is global$init?
This is the script init which is code the compiler generates to define a class and add it to the global object.
3. Can the Profiler be used with Flex 2.0 and Flex 2.0.1 applications?
Yes.
4. Can the Profiler be used with Flash Authoring AS3 based applications?
Yes.
5. Can the Profiler be used with AS2 applications?
No.
6. Is Adobe AIR profiling supported?
Not in beta 1.
Known Issues
- SDK-11083 Application loaded with the IE Active X player does not send data to the profiler. Workaround: Change the preferences to use Firefox or launch .swf file instead of .html to launch in the standalone player.
- SDK-11179 To change the web browser for launching via Flex Development perspective, the preferences should be changed from Windows -> Preferences -> General -> Web Browser.
To change the web browser for launching via Flex Profiling perspective, then preferences should be changed from Windows -> Prefernces -> Flex -> Profile -> Browser/Player.
- SDK-11073 Any changes made to Profiler preferences (Windows -> Prefernces -> Flex -> Profile) does not get applied. Workaround: Flex builder needs to be restarted in order for preferences to take effect.
- SDK-11167 Allocation Trace Panel does not show any data if object allocation stack trace option is not selected. Workaround: To view Allocation Trace, select the option for object allocation stack trace during swf launch. Selecting the object allocation stack trace may slow down the profiling.
- SDK-11133 Filters gets added but don't get applied.
- SDK-11131 Concurrently profiling multiple applications is not reliable for this beta. Workaround: Profile one application at a time.
- SDK-11044 Profiler will not close applications launched in browser. Workaround: To terminate the profiling session, close the browser.
- SDK-11025 Object references panel may contain some Duplicate entries.
- SDK-9421 Object references panel may contain some GCed objects, for these entries the references can not be expanded.
- SDK-9621 For some methods, performance profile may shows Function Self Time as zero.
- SDK-11084 Currently data in method statictics is same as in Performance profile panel. It is not disaggregated in case a method is called from multiple locations.
- SDK-11026 Method statistics panel does not show callee and caller data for private and protected methods.
- SDK-11101 In some cases live objects panel data may not match with the memory snapshot data.
- SDK-11139 In some cases Null pointer exception may be encountered while taking a memory snapshot. Workaround: Restart profiling session and disable performance profiling.