In many instances, the code that you write is not as efficient as you would like to be. In this article, you will learn how to use profiling tools available in WSAD 5.0 to help you identify memory leaks, thread issues, and method response times in your code.
Initial Setup
The IBM Agent Controller must be installed for the Profiling Tool to function.
The WSAD 5.0 installation comes with an optional installation of the IBM Agent Controller. After the IBM Agent Controller is installed, the “serviceconfig.xml” properties file must be inspected to make sure that it is pointing to the correct installation directory of the WSAD. By modifying the properties file, you can modify the location of where the profiling results will be written. You also can modify the host name and port number of the agent as well as the logging level. The IBM Agent Controller can be stopped and started as a Windows service from the Control Panel –> Administrative Tools –> Services.
When you first launch the WSAD after the IBM Agent Controller is installed, you must set the profiling and logging preferences.
- From the WSAD main menu, select Window –> Preferences –> Profiling and Logging. You have to make sure that the “Enable Profiling” and “Enable Logging” checkboxes are checked. The Agent Controller local port number must match the port number specified in the “serviceconfig.xml” file of the controller (See Figure 1).
- From the WSAD main menu, select Window –> Preferences –> Profiling and Logging –> Hosts. Here, you have to make sure that the default host for the agent controller is set up and is successfully connecting to the agent. The host should automatically get set.If it does not, add a new default host where host name and port number correspond to the parameters that are specified in “serviceconfig.xml”. You can test the connection by clicking on the “Test Connection” button.
Figure 1
Figure 2
Hands-on Example: Identifying Memory Leaks
In the first example, you will walk through a memory leak that you will identify using the profiling tool. Then, you will fix the leak, rerun the profiling session, and compare the difference.
First, let me define a memory leak. A memory leak is bug in a program that prevents it from freeing up memory that it no longer needs. As a result, the program grabs more and more memory until it finally crashes because there is no more memory left.
Now that you know the definition of a memory leak, try to find it in the following code. (The link to the full source code of this class, ProfileTestOne.java, is located in the zip file at the end of this article.)
1. public void leakingVector(int iter, int count) { 2. for (int i = 0; i < iter; i++) { 3. for (int n = 0; n < count; n++) { 4. vector.add(new DummyClass(n + i)); 5. } 6. for (int n = count - 1; n > 0; n--) { 7. vector.removeElementAt(n); 8. } 9. } 10. }
Line 6 is where the leak occurs. The code does not remove the last element from the vector. With every call to the leakingVector () method, the vector will have more and more data in it and, after some period of time, it could crash the JVM.
Now, you can profile this method using the Profiler. The main method looks like this:
1. public static void main(String[] args) throws IOException { 2. ProfileTestOne javaLeaks = new ProfileTestOne(); 3. for (int i = 0; i < 100 ; i++) { 4. javaLeaks.leakingVector (100, 10); 5. } 6. }
The main method invokes the leakingVector () methods 100 times. You need to follow these seven steps to set up and launch a profiling session:
- To configure the profiling process, click on Profile –> Launch –> Java Process.
- Select the project name and the class that you are profiling and click “Next” (see Figure 3). You can specify any execution parameters that the application requires. For the example, you do not require any execution parameters.
- On this panel (see Figure 4), you have the option to set the filters for profiling agents that you want to use during the profiling session. The filters allow you to exclude packages that you do not want to see on the profiling report.
- On the next panel (see Figure 5), you can set the options that control the data that is collected by the profiling agents during the profiling session. You can profile for memory usage that will reveal how many instances are still alive and the memory size allocated by every class. You also can analyze the application execution time and see how many methods were called and how long it takes to execute every method. For the first example, you will click on the first checkbox to check for memory leaks.
- On this panel (see Figure 6), you can set the limit of the amount of data that is collected by profiling agents during the profiling session.
- Click “Finish”. The profiling session has started.
- Now, modify the method so that all instances of the DummyClass are removed from the vector. In the code below, on line 6, you replaced the “greater than” condition with “greater than or equals to” condition.
Figure 3
Figure 4
Figure 5
Figure 6
During the profiling session, you use the Profiling Perspective to observe the results. Right-click on the default monitor –> Open With –> Package Statistics. The table in the package statistics view shows you that out of 100,000 created instances of the DummyClass, only 90,000 had been collected by the garbage collection. (See Figure 7.)
Figure 7
1. public void noLeak(int iter, int count) { 2. for (int i = 0; i < iter; i++) { 3. for (int n = 0; n < count; n++) { 4. vector.add(new DummyClass(n + i)); 5. } 6. for (int n = count - 1; n =& 0; n--) { 7. vector.removeElementAt(n); 8. } 9. } 10. }
After profiling your modified code, you can observe that the number of “Live Instances” of the DummyClass is 0 and the number of “Collected” instances equals to the number “Total” instances of the DummyClass. (See Figure 8.)
Figure 8
In this example, you have observed that the use of this profiling tool helps you identify and correct memory leaks.
Hands-on Example: Identifying Method Response Times
In the second example, you will identify method response times using the WSAD Profiling Tool. In the class below, you are calling a number of methods that each sleep for a predefined number of seconds. In this example, you will repeat Steps 1–7 from the previous section. (The link to the full source code of this class, ProfileTestTwo.java, is located in the zip file at the end of this article.)
1. package com.profile.examples; 2. 3. public class ProfileTestTwo { 4. 5. public void methodOne() throws InterruptedException { 6. Thread.sleep(1000); 7. } 8. 9. public void methodTwo() throws InterruptedException { 10. Thread.sleep(2000); 11. } 12. 13. public void methodThree() throws InterruptedException { 14. Thread.sleep(3000); 15. } 16. 17. 18. public static void main(String[] args) throws InterruptedException{ 19. ProfileTestTwo testTwo = new ProfileTestTwo(); 20. for (int i = 0; i < 10 ; i++) { 21. testTwo.methodOne(); 22. testTwo.methodTwo(); 23. testTwo.methodThree(); 24. } 25. } 26. }
This time, you are interested in a different Profiling Perspective to observe the results. After the profiling session finishes its execution, right-click on the default monitor –> Open With –> Method Statistics.
Figure 9
You can observe that the methodThree() method takes the longest cumulative time because it spends the longest amount of time in sleeping mode.
Conclusion
In this article, you have learned how to use the WSAD Profiling Tool to identify memory leaks and method invocation times. The tool benefits developers because it is a means to identify issues that are not evident on the surface.
Download the Code
You can download the code that accompanies this article here.
About the Author
Aleksey Shevchenko has been working with object-oriented languages for over seven years. He has been implementing Enterprise IT solutions for Wall Street and the manufacturing and publishing industries.