![]() |
![]() |
![]() |
![]() |
4 Using the memory profiler
The memory profiler provides information about the objects allocated by your Java program. It displays all allocated instances in real time, and allows you to see precisely which method is responsible for object allocations.
In addition, the memory profiler provides a powerful way to browse incoming and outgoing object references.
Using the OptimizeIt memory profiler, you can improve the performance of your program by:
· Minimizing temporary object allocations. Excessive temporary object allocations can cause the garbage collector to run every few seconds. When running, the garbage collector slows down your Java program.
· Minimizing the number of instances required for a given operation, and therefore decreasing the memory that your program requires.
· Reducing memory waste by making sure every object is garbage collected.
4.1 Memory profiler modes
The memory profiler provides many views into the profile information. Switch between these views, called "modes," using the buttons in the toolbar:
4.2 Understanding object allocations
By default when your program is started, OptimizeIt appears in the Heap mode, displaying all classes and the number of instances currently allocated. The following picture shows the Heap mode:
To sort the values in a column of the table, click the column header.
The filter on the bottom of the window allows you to select the classes that you want to see. For example, to only see all the AWT classes, type:
java.awt.*
Both the asterisk wildcard character (*) and the not (!) are supported. It is possible to enumerate more than one pattern using a comma (,) separator.
For example, to see all classes matching "image" except java.awt.Image classes type:
*image*, !java.awt.Image*
To see all classes, clear the filter completely, or type an asterisk (*).
Click the "Disable garbage collector" option to study object allocations without having the garbage collector removing instances. OptimizeIt "Disable garbage collector" option disables the garbage collector logically for the heap mode.
The garbage collector is not really disabled, however the heap mode shows you what would happen if the garbage collector was not running.
You can also click the Run Garbage Collector button to explicitly run the garbage collector.
Click the Mark button to mark the current instance count. A mark appears on each graph of the instance. This mark represents the number of instances allocated at the time you set the mark. The time difference is then set to zero for all classes. The mark allows you to see the instances allocated by a specific action in your program.
For example, click the Mark button, and then open one of the test program dialog boxes. Click the Diff column header to sort the column so you can see the instances allocated when the dialog box was created. The Allocation Backtrace and Instance Display modes also display information relative to a mark.
Refining the Heap mode display
The Inspector window provides options to refine the Heap mode display. To open the Inspector window, click the Inspector button.
The Inspector window contains the following options for Heap mode:
4.3 Understanding where objects are allocated
After you have identified a class with an excessive number of instances, the next step is to identify the code or the part of the program that is responsible for these allocations. In Heap mode, select the line displaying the class you want to focus on, and click the Show Allocation Backtraces button. OptimizeIt switches to Allocation Backtrace mode. Allocation Backtrace mode shows which code is responsible for the selected class object allocations.
The following picture shows allocation backtrace mode:
The top section in Allocation Backtrace mode traces calls from the first method of the Java program to where allocations occur. The purpose of this view is to understand which feature of your program is responsible for object allocations. By opening nodes in this view, you can see precisely where allocations originate. Any line with an allocation icon (
) is a line that is responsible for one or more object allocations.
The bottom section displays the names of methods responsible for object allocations. The purpose of this view is to quickly understand if a single method performs excessive allocations.
By pressing the Reverse Display button in the toolbar, you can reverse the lists to display backtraces from the place where the allocations take place to the Main method of the Java program. This view can be useful when you need to focus on methods or lines of code responsible for object allocations rather than broad features of your program.
To display the code corresponding to a line in the top or bottom sections of the window, select the line, then click the Show Source Code button. You can also double click the line to show the source code. For more information, see "Viewing source code" in chapter 7.5.
Refining the Allocation Backtrace mode display
The Inspector window provides options to refine the Heap mode display. To open the Inspector window, click the Inspector button.
The Inspector window contains the following options for Allocation Backtrace mode:
4.4 Tracking temporary object allocations
Excessive temporary object allocations are often a source of performance problems in Java programs. Although allocating an object is a fast operation on most Java virtual machines, excessive temporary objects keep the garbage collector busy. Running the garbage collector can block the Java program for as much as a couple hundred milliseconds. If the garbage collector has to run very often, these interruptions cause the Java program to appear slow to the user.
Temporary objects are hard to track without OptimizeIt because some Java APIs allocate many temporary objects.
Tracking down excessive temporary object allocations
1. Click the Show Heap button.![]()
2. Click the Instance Count column header to sort the display.
3. Exercise your program, noting the classes that show quick changes in their number of instances.
4. Select one of these classes.
5. Click the Run Garbage Collector button to free current temporary objects.![]()
6. Click the Mark button to place a mark on the currently allocated instance.![]()
7. Exercise your program again to recreate the problem.This time the garbage collector is disabled and the number of instances does not decrease.
8. Click the Show Allocation Backtraces button.![]()
9. Click the Show Inspector button.![]()
10. Select the option "Since last mark" to only display newly allocated objects.
The Allocation Backtrace mode displays the code responsible for the allocations.
After you have identified which line of code or API is responsible for all these objects, change your program so it uses different APIs or reuses the same objects.
4.5 Identifying objects not freed by the garbage collector
In a development environment that has no garbage collector, a program that does not free the allocated memory loses this memory, creating a "memory leak." With Java's garbage collector, it is no longer necessary for programmers to keep track of allocated objects and free them explicitly when they are no longer required.
However, it is quite common for a Java program to keep some references to some objects that are not really necessary anymore. For example, take a Java program that displays a splash screen at startup. The splash screen image can be quite heavy and is necessary only during startup. If a static variable somewhere references an object that has a hashtable that references the splash screen image, the image will never be garbage collected because it is still accessible from the Java program. Thus, the program requires more resources than necessary to maintain the splash screen image. This situation is similar to a memory leak in non garbage collected environments.
To solve this kind of problems, OptimizeIt Professional provides an Instance Display mode. This mode displays all instances of a given class and their incoming and outgoing references. Incoming references are references from an object to the selected object. Outgoing references are references from the selected object to other objects.
To switch to Instance Display mode, press the Show Instance button. The following picture shows the Instance Display mode displaying some incoming references:
![]()
The top view displays the string representations of the selected class instances. Instances are sorted by allocation date, with the most recently allocated instances on top. The string representations are obtained by calling the method toString() on each object. By implementing useful toString() methods in your classes you can use this view to identify the currently allocated instances.
The middle view displays the objects that are referenced by the object selected in the top view. When available, the instance variable that references the object is in bold.
If a cycle is found in the graph, the point where the cycle occurs is displayed with the
icon.
Reduced reference graph
With JDK 1.2, OptimizeIt provides a reduced reference graph. A reduced reference graph is the transitive closure of the full reference graph. If an object A is referenced by B and D, and if D also references B, the reference D->A won't be displayed. This mode is extremely interesting to understand which reference should be removed in order to allow the selected object to be garbage collected. All displayed references are references preventing the object from being garbage collected.
The following picture shows the Instance Display mode displaying the reduce reference graph:
![]()
In the example above, the vector selected in the top view cannot be garbage collected because it is referenced by the member variable "listeners" of an event object which itself is referenced by the "changeSupport" member variable of a JTabbedPane. Clearing any of these reference will allow the Vector to be garbage collected.
The standard incoming reference graph is also provided. Click on the reference column header and select Reference graph.
Outgoing references
OptimizeIt can also display out-going references. To display outgoing references, click the Reference Graph column header, and then select Instance variables retaining objects. The following picture shows the Instance Display mode with outgoing references:
The middle view displays objects that are referenced by the object selected in the top view. Icons indicate the meaning of each line:
To display the code corresponding to a line in the middle or bottom sections of the window, select the line, then click the Show Source Code button. You can also double click the line to show the source code. For more information, see "Viewing source code" in chapter 7.5.
Refining Instance Display mode display
The Inspector window provides options to refine the Instance Display mode display. To open the Inspector window, click the Inspector button.
The Inspector window contains the following options for the Instance Display mode:
Browsing references from roots
With Java 2, OptimizeIt allows you to browse references from roots. Roots are the roots of the reference graph and include:
· Busy monitors
· Class static variables
· Class constants
· JNI global and local references
· Threads Java and native stacks
With this mode, you can see the entire content of the heap and understand exactly the hierarchy between the different objects. The following picture shows the Browsing references from roots mode:
![]()
In this example, the stack of the thread AWT-EventQueue-0 references an instance of PaintEvent, which itself references the frame of the application, which references through its containerListener various graphical objects of the application.
The icons used in the graph have the following meaning:
If the selected row in the top view is an object, the bottom view displays where the object was allocated. As usual, double clicking on the row or clicking on the
button shows the source code corresponding to the selection.
Intuitive Systems http://www.optimizeit.com optimizeit@intuisys.com |
![]() |
![]() |
![]() |
![]() |