Identify problem areas

You can use various techniques to identify problem areas in your applications by using the profiler.

Locate memory leaks

One of the most common problems you face in application development is memory leaks. Memory leaks often take the form of objects that were created within a period but not garbage collected.

One way to identify memory leaks is to look at the number of references to an object in the Instances table in the Object References view. You can generally ignore references from document properties and bindings, and look for unexpected or unusual references, especially objects that are not children of the object. For more information, see Object References view.

You can also examine paths to instances of an object to determine if a path has a back-reference to the garbage collector (GC Root). An instance that was expected to be released, but has references to GC Root, indicates a memory leak. In these cases, modify your application code so references to GC Root are removed. An instance that has no references to GC Root is ready for garbage collection. Flash Player eventually frees this memory.

Another way to locate memory leaks is to compare two memory snapshots in the Loitering Objects view to determine which objects are still in memory after a particular series of events.

Common ways to clean up memory links are to use the disconnect(), clearInterval(), and removeEventListener() methods.

Find a back-reference to GC Root for an instance

  1. Create a memory snapshot.

    See Create and view a memory snapshot.

  2. Specify the number of back-reference paths to find.

    From the Memory Snapshot view, specify the maximum number of paths to find, or select Show All Back-Reference Paths.

  3. Double-click a class in the memory snapshot to open the Object Reference view.

  4. Expand the listed paths to and examine if there is a back-reference to GC Root.

Find loitering objects

  1. Create two memory snapshots.

    See Create and view a memory snapshot.

  2. Select the two memory snapshots to compare.

    Note: If you have more than two memory snapshots, you cannot select a third one. You can compare only two memory snapshots at one time.
  3. Click the Find Loitering Objects button.

    Loitering Objects view shows you potential memory leaks. The Instances and Memory columns show the differences between the number of instances of a class and the amount of memory consumed by those instances during the interval between one snapshot and the next. If you see a class that you did not expect to be created during that time, or a class that you expected to be destroyed during that time, investigate your application to see if it is the source of a memory leak.

  4. To determine how an object in the Find Loitering Objects view was instantiated, double-click the object in the view. The Object References view shows you the stack trace for each instance that you selected.

One approach to identifying a memory leak is to first find a discrete set of steps that you can do over and over again with your application, where memory usage continues to grow. It is important to do that set of steps at least once in your application before taking the initial memory snapshot so that any cached objects or other instances are included in that snapshot.

Then you perform that set of steps in your application a particular number of times—3, 7, or some other prime number—and take the second memory snapshot to compare with the initial snapshot. In the Find Loitering Objects view, you might find loitering objects that have a multiple of 3 or 7 instances. Those objects are probably leaked objects. You double-click the classes to see the stack traces for each of the instances.

Another approach is to repeat the sequence of steps over a long period and wait until the memory usage reaches a maximum. If it does not increase after that, there is no memory leak for that set of steps.

Common sources of memory leaks include lingering event listeners. You can use the removeEventListener() method to remove event listeners that are no longer used. For more information, see Object creation and destruction in Using Flex 4.6.

Analyze execution times

By analyzing the execution times of methods and the amount of memory allocated during those method calls, you can determine where performance bottlenecks occur.

This is especially useful if you can identify the execution time of methods that are called many times, rather than methods that are rarely called.

Determine frequency of method calls

  1. Start a profiling session and ensure that you enable performance profiling when configuring the profiler on the startup screen.

  2. Select your application in the Profile view.

  3. Interact with your application until you reach the point where you want to start analyzing the number of method calls. To see how many times a method was called from when the application started up, do not interact with the application.

  4. Click the Reset Performance Data button. This clears all performance data so that the next performance profile includes any data from only this point forward.

  5. Interact with your application until you reach the point where you check the number of method calls since you reset the performance data.

  6. Click the Capture Performance Profile button.

  7. Double-click the performance profile in the Profile view.

  8. In the Performance Profile view, sort the data by the Method column and find your method in the list.

    The value in the Calls column is the number of times that method was called during this sampling interval. This is the time between when you clicked the Reset Performance Data button and when you clicked the Capture Performance Profile button.

Examine the values in the Cumulative Time, Self Time, Avg. Cumulative Time, and Avg. Self Time columns of the Performance Profile view. These show you the execution time of the methods.

Compare the time each method takes to execute against the time that all the methods that are called by a particular method take to execute. In general, if a method’s self-time or average self-time are high, or high compared to other methods, look more closely at how the method is implemented and try to reduce the execution time.

Similarly, if a method’s self-time or average self-time are low, but the cumulative time or average cumulative time are high, look at the methods that this method calls to find the bottlenecks.

Locate excessive object allocation

One way to identify trouble areas in an application is to find out where you might be creating an excessive number of objects. Creating an instance of an object can be an expensive operation, especially if that object is in the display list. Adding an object to the display list can result in many calls to style and layout methods, which can slow down an application. In some cases, you can refactor your code to reduce the number of objects created.

After you determine whether there are objects that are being created unnecessarily, decide whether it is reasonable or worthwhile to reduce the number of instances of that class. For example, you could find out how large the objects are, because larger objects generally have the greatest potential to be optimized.

To find out which objects are being created in large numbers, you compare memory snapshots of the application at two points in time.

View the number of instances of a specific class

  1. Start a profiling session and ensure that you enable memory profiling when configuring the profiler on the startup screen.

  2. Interact with your application until you reach the place to take a memory snapshot.

  3. Click the Take Memory Snapshot button. The profiler adds a new memory snapshot to the application list in the Profile view.

  4. Open the memory snapshot by double-clicking it in the Profile view.

  5. To view the number of instances of a particular class, and how much memory those instances use, sort by the Class column and find your class in that column. You can also sort by the other columns to quickly identify the objects that take up the most memory or the objects with the most instances. In most cases, Strings are the class with the most instances and the most memory usage.

For more information about the Memory Snapshot view, see Memory Snapshot view.

Locate instances of excessive object allocation

  1. Start a profiling session and ensure that you enable memory profiling when configuring the profiler on the startup screen.

  2. Interact with your application until you reach the first place to take a memory snapshot.

  3. Click the Take Memory Snapshot button.

    The profiler saves the memory snapshot in the Profile view, and marks the snapshot with a timestamp.

  4. Interact with your application until you reach the second place to take a memory snapshot.

  5. Click the Take Memory Snapshot button again.

    The profiler saves the second memory snapshot in the Profile view, and marks the snapshot with a timestamp.

  6. Select the two memory snapshots to compare.

    Note: If you have more than two memory snapshots, you cannot select a third one. You can compare only two at a time.
  7. Click the View Allocation Trace button.

    The Allocation Trace view shows which methods were called between the two snapshots and how much memory was consumed during those method calls. See Allocation Trace view.