| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" | |
| content="text/html; charset=windows-1252"> | |
| <title>Java Application Profiling using TPTP</title> | |
| <link rel="stylesheet" href="../default_style.css"> | |
| </head> | |
| <body link="#0000ff" vlink="#800080"> | |
| <div align="right"> <font face="Times New Roman, Times, serif" | |
| size="2">Copyright © 2006 International Business Machines Corp.</font> | |
| <table border="0" cellpadding="2" cellspacing="0" width="100%"> | |
| <tbody> | |
| <tr> | |
| <td colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font | |
| face="Arial,Helvetica"><font color="#ffffff"> Eclipse Corner | |
| Article</font></font></b></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div align="left"> | |
| <h1><img src="images/Idea.jpg" align="middle" height="86" width="120"></h1> | |
| </div> | |
| <p> </p> | |
| <h3>Java Application Profiling using TPTP<br> | |
| </h3> | |
| <blockquote> <b>Summary</b> <br> | |
| <br> | |
| The Eclipse Test & Performance Tools Platform (TPTP) Profiling tool | |
| can be used to profile Eclipse plug-ins, | |
| local Java(TM) | |
| applications or complex applications running on multiple hosts and | |
| different platforms. | |
| The tool is tightly integrated with Eclipse, allowing profiling of | |
| applications running from within Eclipse. <br> | |
| This article demonstrates how | |
| to use the TPTP Profiling tool to profile | |
| a Java application for identifying execution related hot spots. It | |
| shows | |
| how to start the profiling session, use the various TPTP | |
| views to analyze the data, identify methods with high execution time | |
| then jump to the source code to fix the performance problem.<br> | |
| <p><b> By Valentina Popescu, IBM<br> | |
| <br> | |
| </b> <font size="-1">February 21, 2006 (updated July 11, 2006)<br> | |
| <br> | |
| </font> </p> | |
| </blockquote> | |
| <hr width="100%"><br> | |
| <h3>Profiling an Application<br> | |
| </h3> | |
| In the current environment of short development cycles for delivering a | |
| product, developers tend to focus more on the functional aspects of | |
| application execution, mostly via testing, debugging, and code fixing. | |
| However, many problems do not easily surface until the application is | |
| running in production mode, 24 hours a day, 7 days a week and gets | |
| pushed to limits during some unexpected peak periods. <br> | |
| <br> | |
| The kinds of performance problems encountered in production cannot be | |
| discovered during a | |
| debugging | |
| session. Before deployed and run in production mode, it is important to | |
| use a Profiling tool to analyze application execution and identify | |
| performance problems, such as execution | |
| bottlenecks, object leaks, and system resource limitations.<br> | |
| This article provides an introduction to the TPTP | |
| Profiling | |
| tool. It demonstrates how to use the TPTP Profiling tool to profile | |
| a Java application in order to identify performance hot spots, | |
| and fix and validate performance problems.<br> | |
| <br> | |
| <h3>TPTP Profiling Tool</h3> | |
| The Eclipse Test & Performance Tools Platform <a | |
| href="http://eclipse.org/tptp/">(TPTP)</a> Project | |
| offers a profiling tool for identifying and isolating performance | |
| problems such | |
| as performance bottlenecks, object leaks and system resource limits. | |
| The tool | |
| targets applications of all levels of complexity, from simple | |
| standalone <span | |
| style="font-size: 12pt; font-family: "Times New Roman";">Java</span> | |
| applications to Eclipse plug-ins or complex enterprise | |
| applications running | |
| on multiple | |
| machines and on different platforms. | |
| <br> | |
| <br> | |
| Being tightly integrated with the Eclipse project, the tool | |
| is also easy to use and extend. That means that users can plug in their | |
| preferred views to analyze the data, or can extend the data collection | |
| metaphor | |
| by implementing their own flavor of data collection agent.<br> | |
| <br> | |
| This article was written using the TPTP 4.2.0 based on the EMF 2.2.0 | |
| and | |
| XSD 2.2.0 release builds, which require Eclipse 3.2.0. You can download | |
| these drivers from <a | |
| href="http://www.eclipse.org/tptp/home/downloads/downloads.php?link=link1&ver=4.2.0">here</a>. | |
| For TPTP 4.2.0 installation details go to the <a | |
| href="http://www.eclipse.org/tptp/home/downloads/installguide/InstallGuide42.html">TPTP | |
| download | |
| page</a>.<br> | |
| <br> | |
| <br> | |
| <h3>Profiling a Java application using TPTP<br> | |
| </h3> | |
| <div style="text-align: left;">The product catalog sample used in this | |
| article | |
| is a simple Java application that parses product | |
| information stored in separate xml files and prints the result to the | |
| console output. The file system location for the folder containing the | |
| product xml files is passed as a program argument when running | |
| the main class, <span style="font-style: italic;">Product.java</span>. | |
| The xml files containing the product information are provided under the | |
| section <a href="#RunningTheExample">running | |
| the example</a>.<br> | |
| <br> | |
| <h4>Starting the application in profiling mode</h4> | |
| After installing the sample application, the | |
| first step is to run the product catalog application in profiling mode. | |
| Profile | |
| the application by using the <span style="font-style: italic;">Profile | |
| As > Java Application</span> | |
| popup-menu on the Product class as seen in the image below. <br> | |
| <br> | |
| </div> | |
| <div style="text-align: center;"><img alt="" | |
| title="Profile the Product application" | |
| src="images/n_profileAction.jpg" style="width: 699px; height: 603px;"><br> | |
| <br> | |
| </div> | |
| <p style="text-align: center;"><b style="">Figure | |
| 1</b> Profile the <span style="font-style: italic;">Product catalog </span>Application<br> | |
| <br> | |
| </p> | |
| <p style="text-align: left;"><img alt="" title="tip" | |
| src="images/tip.gif" style="width: 62px; height: 13px;">Another way of | |
| starting the application in profiling mode is to use the <span | |
| style="font-style: italic;">Profile</span> | |
| action available on the Java perspective's toolbar menu. Similar to | |
| the | |
| <span style="font-style: italic;">Run </span>and <span | |
| style="font-style: italic;">Debug </span>toolbar actions, the <span | |
| style="font-style: italic;">Profile </span>action will open the | |
| launch configuration dialog and from there you can select the type of | |
| application you want to profile.<br> | |
| | |
| <br> | |
| </p> | |
| <h4>Setting the Java program arguments</h4> | |
| <p style="text-align: left;">The <span style="font-style: italic;">Profile | |
| As > Java Application </span>action will open the launch | |
| configuration wizard as displayed by Figure 2.</p> | |
| <p style="text-align: left;">For this example, the folder | |
| containing the product xml files is passed as a program | |
| argument. As described in the Figure 2 below, set the program arguments | |
| to be <span style="font-style: italic;">x:\myPath\products</span>, | |
| where <span style="font-style: italic;">x:\myPath </span>is the path | |
| where you have unzipped the folder containing the product xml files | |
| provided at the end of this article.<br> | |
| </p> | |
| <div style="text-align: center;"><img alt="Program arguments" | |
| title="Program arguments" src="images/args.gif" | |
| style="width: 591px; height: 585px;"><br> | |
| <br> | |
| <span style="font-weight: bold;">Figure 2</span> <span | |
| style="font-style: italic;">Product catalog</span> sample - program | |
| arguments<br> | |
| </div> | |
| <p style="text-align: left;"><span style="font-weight: bold;"></span></p> | |
| <h4><br> | |
| </h4> | |
| <h4>Setting profiling filters</h4> | |
| The next step is | |
| to set the profiling options to collect method execution information.<br> | |
| To set these options, click the Monitor tab on the Launch Configuration | |
| Properties wizard and select a set of profiling options that fits with | |
| your performance investigation.<br> | |
| <br> | |
| <img alt="" src="images/tip.gif" style="width: 62px; height: 13px;">A | |
| Profiling filter set is a | |
| reusable set of profiling filters. | |
| The purpose of creating profiling filter sets is to reuse them | |
| during consecutive runs of the same application or to share them | |
| between applications that require the same type of profiling | |
| information.<br> | |
| The steps below describe how to create a new filter set used to | |
| profile the Product catalog application. We will be creating a new | |
| filter set named ProductFilterSet which will be used to profile only | |
| packages that have the | |
| <span style="font-style: italic;">com.sample.product</span> prefix.<br> | |
| <br> | |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;">1. Choose to | |
| collect execution details by | |
| selecting the Execution Time Analysis option in the Monitor tab. <br> | |
| <br> | |
| </p> | |
| <div style="text-align: center;"><img | |
| alt="Execution Time Analysis option" | |
| title="Execution Time Analysis option" src="images/execOption.gif" | |
| style="width: 542px; height: 490px;"><br> | |
| </div> | |
| <p style="text-align: center;"><b style="">Figure 3</b> Execution Time | |
| Analysis option<br> | |
| </p> | |
| <p style="text-align: left;">As shown in Figure 3 above we have | |
| selected the Execution Time Analysis option that can be used during | |
| consecutive runs of the | |
| product catalog application. On the next run of this application, the <span | |
| style="font-style: italic;">Setting Profiling Filters</span> step can | |
| be skipped.<br> | |
| <br> | |
| </p> | |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;">2. Select Edit | |
| Options action to set the profiling execution options.</p> | |
| <p style="margin-left: 1cm; text-indent: -0.5cm;">2a. Select the | |
| "Collect | |
| boundary classes excluded by the filter set" option and enter 3 as the | |
| Boundary class depth value. </p> | |
| <p style="margin-left: 1cm;">By selecting this option, you specify that | |
| you want to collect | |
| information for methods invoked to the specified depth starting with | |
| the methods in your filter criteria.</p> | |
| <p style="margin-left: 1cm;">As an example, let's assume that we have | |
| set | |
| the filter to collect information on method MyMethod and to filter out | |
| methods | |
| M1, M2, M3, M4.</p> | |
| <p style="margin-left: 1cm;">If the following invocation stack is | |
| executed: MyMethod > M1 > | |
| M2 > M3 > M4 ( MyMethod invokes M1 which invokes M2 which invokes | |
| M3 which invokes M4 ), based on the filtering criteria selected at | |
| point 2a, the profiler will show this call stack: MyMethod > | |
| M1 > M2 > M3 and will not display the last invocation M3 > M4 | |
| (since this exceeds the specified depth of 3).</p> | |
| <p style="text-align: center;"><img alt="Profiling Execution options" | |
| title="Profiling Execution options" src="images/profOptions.gif" | |
| style="width: 454px; height: 481px;"><br> | |
| </p> | |
| <p style="text-align: center;"><span style="font-weight: bold;">Figure 4</span> | |
| Choose to collect execution information<br> | |
| </p> | |
| <br> | |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;">3. Select the | |
| classes to be profiled. <br> | |
| </p> | |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;"> | |
| In the Monitor tab, select the Java Profiling item and double click or | |
| select Edit Options action. The Filter Set wizard opens.<br> | |
| Use the Filter Set page to choose the classes you want to profile. | |
| There are a set of predefined filters available but for this sample you | |
| will create a new filter set named ProductFilterSet which filters out | |
| everything except packages prefixed by com.sample.product.<br> | |
| Follow these steps to create the filter set:<br> | |
| </p> | |
| <p style="margin-left: 1cm; text-indent: -0.5cm;">3a) Select the Add... | |
| action from the filter set list. In | |
| the result dialog enter ProductFilterSet as the name of the new filter | |
| then click OK</p> | |
| <p style="margin-left: 1cm; text-indent: -0.5cm;">3b) Use the Add... | |
| button from the Contents of selected | |
| filter set list to create the two filters as shown in Figure 5.</p> | |
| <br> | |
| <div style="text-align: center;"><img | |
| alt="Select the classes to be profiled" | |
| title="Select the classes to be profiled" src="images/n_pSetP3.jpg" | |
| style="width: 627px; height: 568px;"><br> | |
| <br> | |
| <span style="font-weight: bold;">Figure 5</span> Choose classes you | |
| want to profile<br> | |
| </div> | |
| <div style="text-align: center;"><br> | |
| <div style="text-align: left;"><br> | |
| <h4>Run the application</h4> | |
| </div> | |
| </div> | |
| <br> | |
| Run the Product catalog application by pressing OK on the Launch | |
| Configuration | |
| wizard. Choose Yes when asked to switch to the Profiling and Logging | |
| perspective.<br> | |
| You should see the result of the program execution in the Console view, | |
| similar with what is presented in Figure 6 below. <br> | |
| <br> | |
| <br> | |
| <div style="text-align: center;"><img | |
| alt="Product application terminated" | |
| title="Product application terminated" src="images/n_profileApp.jpg" | |
| style="width: 753px; height: 600px;"><br> | |
| <b style=""><br> | |
| Figure 6</b> Product catalog application has been executed<br> | |
| <br> | |
| <br> | |
| <div style="text-align: left;"><img alt="" src="images/tip.gif" | |
| style="width: 62px; height: 13px;"> The TPTP profiling tool allows you | |
| to | |
| interact with your profiled application. You can pause and resume | |
| monitoring, run garbage collection on the profiled application, collect | |
| object references or terminate the application.<br> | |
| </div> | |
| </div> | |
| <span style="font-weight: bold;"><br> | |
| <br> | |
| </span> | |
| <h4>Identify performance hot spots using the Execution Statistics view</h4> | |
| <br> | |
| Use the Execution Statistics view to identify performance hot spots. To | |
| open this view, select the process in the Profiling Monitor | |
| view and select Open with > Execution Statistics pop-up action.<br> | |
| The Execution Statistic view shown in the Figure 7 below display the | |
| methods executed, sorted by cumulative time. The cumulative time | |
| for a method is the time spent to execute that method, including | |
| any invocations to other methods.<br> | |
| <br> | |
| <br> | |
| <div style="text-align: center;"><img alt="Execution statistics view" | |
| title="Execution statistics view" src="images/n_executionStat.jpg" | |
| style="width: 751px; height: 513px;"><br> | |
| </div> | |
| <div style="text-align: center;"><span | |
| style="font-size: 12pt; font-family: "Times New Roman";"></span><br> | |
| <span style="font-size: 12pt; font-family: "Times New Roman";"></span> | |
| </div> | |
| <p style="text-align: center;" class="MsoNormal"><b>Figure 7</b> | |
| Execution | |
| Statistics View<br> | |
| </p> | |
| As presented in Figure 4, the <b style="">Execution | |
| Statistics</b> shows the main(java.lang.String[]), | |
| readData(java.lang.String) and createParser() methods as the top three | |
| methods with the highest execution time. It is not surprising to see | |
| the main and readData methods on this list since the first one is the | |
| starting point of the application execution while the second as | |
| suggested by it's name, is reading the products data from the xml files.<br> | |
| <br> | |
| What comes as a surprise for us is the fact that createParser() | |
| method, which | |
| just creates a SAX parser instance used to parse | |
| the xml files, has such a high execution time. The execution time for | |
| this method accounts for 42.96% of | |
| the application's total execution time. The Execution Statistics have | |
| helped us to identify this method as a potential place to optimize the | |
| application's performance.<br> | |
| <br> | |
| Once we have identified this, let's drill down and see the | |
| createParser() method's execution details. <br> | |
| <br> | |
| <h4>Open Method Invocation Details view on the createParser() method<br> | |
| </h4> | |
| <br> | |
| <div style="text-align: center;"> | |
| <div style="text-align: left;">We will use next the Method Invocation | |
| Details view to see what methods in the createParser() call stack are | |
| responsible for the method's slow execution time. Open the Method | |
| Invocation Details view by double-click on the createParser() method in | |
| the Execution Statistics view.<br> | |
| <br> | |
| <br> | |
| <div style="text-align: center;"><img alt="Method Invocation Details" | |
| title="Method Invocation Details" src="images/n_mInv.jpg" | |
| style="width: 844px; height: 705px;"><br> | |
| <br> | |
| <span style="font-weight: bold;">Figure 8</span> Method Invocation | |
| Details view<br> | |
| </div> | |
| </div> | |
| <br> | |
| </div> | |
| <br> | |
| Figure 8 below presents the execution information for the | |
| createParser() method. As you can see the method has been invoked once | |
| by the readData(java.lang.String) method and invokes 5 different | |
| methods. In the invoked methods table you can see that newSAXParser() | |
| and newInstance() methods are responsible for the createParser's method | |
| slow execution. These two methods were called 24 times, as the | |
| createParser() method has been executed 24 times.<br> | |
| <br> | |
| <h4>Define a solution for the identified performance problem<br> | |
| </h4> | |
| <br> | |
| By analyzing this data, we found that one way to improve the | |
| createParser() execution time is to improve the execution of the two | |
| SAXParserFactory methods. Since we have no control over these methods' | |
| implementation, the only way to improve our application execution is to | |
| reduce the number of calls we make to these methods.<br> | |
| <br> | |
| The solution is to create one parser instance and reuse it for parsing | |
| all xml files, instead of creating a new parser for every file. Let's | |
| open the source code and apply the fix.<br> | |
| <p style="text-align: left;"><img alt="" title="tip" | |
| src="images/tip.gif" style="width: 62px; height: 13px;">Before making | |
| any such optimizations, make sure that they are supported by the code. | |
| For example, while the SAXParser cannot be simultaneously used by | |
| multiple threads, instances can be reused. Strictly speaking, instances | |
| should be <code>reset()</code>before they are reused. It is also a | |
| good idea to have a comprehensive set of unit tests in place before you | |
| make changes to code that could possibly introduce changes in behavior.</p> | |
| <br> | |
| <h4>Open the source code and apply the performance fix</h4> | |
| To open the source code for the createParser() method, select the | |
| method in the Method Invocation Details view then right-click and | |
| choose the Open Source action on the pop-up menu.<br> | |
| <br> | |
| <br> | |
| <br> | |
| <div style="text-align: center;"> | |
| <div style="text-align: center;"><img alt="Source code" | |
| title="Source code" src="images/n_sourceCode.jpg" | |
| style="width: 815px; height: 693px;"><br> | |
| </div> | |
| <b><br> | |
| Figure 9</b> Source code<br> | |
| <br> | |
| </div> | |
| <p style="text-align: left;">Figure 9 shows the createParser() source | |
| code. Notice that the method creates a new SAX parser instance on every | |
| call.<br> | |
| Update the source code as presented in Figure 10 below so that the code | |
| will create only one parser instance and reuse it when parsing every | |
| xml file.<br> | |
| <br> | |
| </p> | |
| <p style="text-align: center;"><img alt="Source code" | |
| title="Source code" src="images/n_sourceCodeFix.jpg" | |
| style="width: 815px; height: 693px;"><br> | |
| </p> | |
| <p style="text-align: center;"><span style="font-weight: bold;">Figure | |
| 10 </span>Source code fix<br> | |
| </p> | |
| <p style="text-align: left;">As presented in Figure 10, the performance | |
| fix defines a global SAXParser instance. The createParser() method | |
| initializes the parser and returns this instance every time the method | |
| is | |
| called.<br> | |
| </p> | |
| <p style="text-align: left;">Let's go back now and validate the fix by | |
| running the Product catalog application in profiling mode once again.<br> | |
| <br> | |
| </p> | |
| <h4>Validate the performance fix<br> | |
| </h4> | |
| <p style="text-align: left;">To validate the performance fix, select | |
| the Product class in the Java perspective and as described above, | |
| right-click and choose Profile As > Java Application.</p> | |
| <p style="text-align: left;">The Profiling options wizard will not open | |
| again as the previous profiling options will be used to run the | |
| application. After the application is executed, open the Execution | |
| Statistics view and compare the execution time.<br> | |
| Figure 11 shows the execution times after the fix has been applied to | |
| the code:<br> | |
| </p> | |
| <br> | |
| <div style="text-align: center;"> | |
| <div style="text-align: center;"><img alt="Execution Statistics view" | |
| title="Execution Statistics view" src="images/n_executionStatFix.jpg" | |
| style="width: 742px; height: 575px;"><br> | |
| </div> | |
| <br> | |
| </div> | |
| <div style="text-align: center;"><b style="">Figure 11</b> Execution | |
| Statistics view<br> | |
| </div> | |
| <p style="text-align: left;"><br> | |
| </p> | |
| As you can see in the image above, the createParser() execution time is | |
| now only 19% of the application execution, while before the performance | |
| fix has been applied to the code, the createParser() execution time was | |
| almost 43% of the application execution time.<br> | |
| Note that this improvement will prove to be even more valuable as the | |
| number of xml files to be parsed increases, so the fix will reduce the | |
| application execution time exponential as more product files are being | |
| added to the catalog.<br> | |
| <br> | |
| <h3>Conclusion</h3> | |
| This article has shown how the TPTP profiling tool can be used to | |
| identify and solve performance problems. There are more aspects of the | |
| TPTP tool not covered by this article. If you would like to know more | |
| about the tool's capabilities, there are a set of tutorial slides | |
| and User Guides available <a | |
| href="http://www.eclipse.org/tptp/home/documents/index.html">here</a>.<br> | |
| <br> | |
| <h3><a name="RunningTheExample"></a>Running the example</h3> | |
| The file "<a href="productCatalogSample.zip">ProductCatalog_example.zip</a>" | |
| contains the complete source code for the example in this article. | |
| Extract the content of the ZIP file into the Eclipse "plugins" | |
| directory. You will also need the list of product xml files which are | |
| stored in the <a href="xmlProductFiles.zip">products.zip</a> file. | |
| Extract the | |
| content of the products.zip file to a desired location on your file | |
| system and use this path as a program argument when running the Product | |
| catalog | |
| application.<br> | |
| <br> | |
| <p><small>Java and all Java-based trademarks and logos are trademarks | |
| or registered trademarks of Sun Microsystems, Inc. in the United | |
| States, other countries, or both.<br> | |
| <br> | |
| </small></p> | |
| <br> | |
| <br> | |
| </body> | |
| </html> |