| By Tim Boudreau | Article Rating: |
|
| January 20, 2008 11:00 AM EST | Reads: |
16,402 |
Why is this? After all, profilers let you improve the performance of your code.
Well, traditionally, profiling hasn't been much fun. Historically profilers have been standalone tools that ironically can be slow and tedious to work with.
In my own work on the NetBeans 3.5 performance team, using a commercial profiler of that era, my approach was to start NetBeans in the profiler then go chat with a friend for a half-hour while the application started.
See, traditional profilers had two ways of operating. First, polling. This wouldn't slow down the entire application, but you weren't getting an accurate picture of what the application was really doing - and the whole point of profiling is to know what the application is actually doing. Polling is great when you know you might have a performance problem somewhere, but haven't localized it yet, and want a general picture of the hot spots.
Then there's full instrumentation. You get a detailed picture of what's happening in the JVM but you pay a price for that picture: Every method in every class is going to have to phone home with timing information, and getting that information takes time in itself. So the profiler itself slowed down the application tremendously.
The NetBeans profiler was introduced with NetBeans 4.1; in NetBeans 6.0, it's included in the base IDE. It started as an R&D project at Sun Microsystems called JFluid. The idea was to use the technology that debugs use to let you change code in a running application on-the-fly (called either Fix and Continue or Hot Swap). It takes a different approach to profiling and injects profiling code into a running application, potentially only into a particular part of the application. So with the NetBeans profiler, if you want to, you can choose to profile only one method. You will get full profiling data about what that method calls, including JDK classes, if you choose (see Figure 1). The rest of the application runs at full speed. So you don't have to wait a half-hour for it to start; and the data you get is about precisely the code you really wanted to profile.
Usually when you're profiling something, you probably know generally where the problem is, what the entry point is to the code that's slow or allocating too much memory or leaking memory. In other words, there's some part of the code that, when it's called, the problem is observable. When the user clicks a certain button, the GUI freezes, or when a user hits a certain Web page, server memory use spikes. Generally you know where to start, and what a profiler tells you is what's really going on, so that you can find the best place to optimize the code. Having the ability to profile just the code you care about - and do it from inside your IDE - means profiling is a productive, rewarding experience. It makes profiling an application a natural part of the development cycle, as it should be, rather than being something only to be done with great pain when performance troubles strike.
The Heap Walker in NetBeans 6
NetBeans 6.0 introduces a new feature in the profiler: support for heap dumps. A heap dump is a file that contains a graph of all of your application's objects that are in the JVM's memory or heap. Java is a garbage-collected language, and a memory leak is an object that's no longer needed but is still referenced by another object that is needed. So the unneeded object remains in the heap, using memory that could otherwise be reclaimed.
Various tools have been around for a long time, such as HAT (Heap Analysis Tool - now in JDK 6 as jhat, which lets queries be written in JavaScript) that were generally text-based and tools of last resort. In NetBeans 6, the profiler can take a snapshot of the Java heap, and browse and query it graphically. So it's easy to find out which object is holding a reference to an object that should have been garbage-collected.
Taking a heap dump is as simple as starting an application with the Profile command (NetBeans handles the details of specifying the necessary JVM command-line switches - you can also attach to a JVM running on a different machine to profile a remote application). Then just invoke ProfileTake Heap Dump.
Or, if you already have a heap dump file created by the JVM, you can open it with Profile Load Heap Dump. The heap walker will open with the heap dump. The profiler provides three different views of the heap.
The summary view shown in Figure 2 displays high-level information about the environment in which the application was running: the operating system, JDK version, heap size, etc.
The classes view shown in Figure 3 displays a list of every class that's been loaded by the JVM to run the application. The number of object instances and the total size of those instances are displayed for each class.
Notice the References panel in the lower right of Figure 4. You can browse the graph of references to any object down to the ClassLoader roots of the JVM's object graph. An especially useful feature is the context menu entry available on each object in the References section: Show Nearest GC Root.
Use it to have the heap walker expand the chain of references back to the nearest JVM garbage collection root object.
Regression Tests - Making Sure Memory Leaks Don't Recur
Once you've fixed the problem, the next step is to make sure it doesn't recur. If a memory leak has happened once, with an object that's held in memory beyond its useful life, it's highly likely that there's other code in that same body of code that could have similar problems.
JUnit is the de facto standard for unit tests for Java code, so our example will nominally use JUnit, but the technique below is suitable for any testing framework that's plain Java code. When you fix a memory leak, if possible, it's worthwhile to write add a unit test to your project's test suite that proves the memory leak remains fixed.
@Test
public void testMemoryLeak() {
//Get the object locally
Object o = getWhatShouldBeGarbageCollected();
//Make some call that should clear all references to the object doWhateverShouldMakeItUnreferenced();
//Now make a weak reference to it. This will be cleared when we force //garbage collection. If it's not, then
some other code is still holding //a reference to the object.
Reference r = new WeakReference ( o );
//Clear our local reference to it - it should be the only one in the VM o = null;
//Force the system to garbage collect several times for
(int i=0; i < 5; i++) {
System.gc();
System.runFinalizers();
}
//Test that the reference has been cleared
assertNull ( r.get() );
}
What this code does is fairly self-explanatory. We get the object that should become unreferenced after the subsequent method call. We keep a weak reference to it (a reference to an object that doesn't prevent it from being garbage-collected: it will return non-null as long as some other object references the object or the garbage collector hasn't collected it yet). The only slightly non-obvious part of this code is that we repeatedly run System.gc() and System.runFinalizers() in a loop (by the way, these are methods should never be called in application code, but are suitable for this sort of test). The point is that there may be a chain of objects that weakly reference each other, and one garbage collection cycle may not be sufficient to clear the entire chain of objects.
Conclusion
The NetBeans profiler is available in the standard distribution of NetBeans 6 and is a valuable tool for producing quality software, because it makes profiling something that's practical to do on a regular basis, rather than
after a crisis. This is an important fact for software quality: A profiler lets you find your performance problems before your customers find them for you.
Published January 20, 2008 Reads 16,402
Copyright © 2008 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Tim Boudreau
Tim Boudreau is a senior staff engineer at Sun Microsystems. He has been working on the NetBeans project for nine years and is co-author of "NetBeans: The Definitive Guide" from O'Reilly and Associates, and "Rich Client Programming" from Addison Wesley.
- 4th International Cloud Computing Conference & Expo Starts Today
- Publishing Synergy: Blog, Twitter and Ulitzer
- Performance Tuning Essentials for Java
- Cloud Expo New York Call for Papers Deadline December 15
- Google Wave
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Cloud Computing Can Revitalize Your Career as Software Developer
- SOA World Magazine "Readers' Choice Awards" Voting Is Now Open
- Oracle+MySQL Opponents Take to the Barricades
- Virtualization Expo Call for Papers Deadline December 15
- Oracle Faces Growing Price for MySQL
- SpringSource Moving to Spring 3.0
- 4th International Cloud Computing Conference & Expo Starts Today
- Deputy CIO of the CIA to Keynote 1st Annual GovIT Expo
- Publishing Synergy: Blog, Twitter and Ulitzer
- Performance Tuning Essentials for Java
- Cloud Expo New York Call for Papers Deadline December 15
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Google Wave
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Cloud Computing Can Revitalize Your Career as Software Developer
- Oracle-Sun: IBM Reportedly Behind Delay
- Citrix Aims To Cripple VMware’s Cloud Designs
- Oracle Trashes HP Relationship for Sun
- After Ubuntu, Windows Looks Increasingly Bad, Increasingly Archaic, Increasingly Unfriendly
- SCO CEO Posts Open Letter to the Open Source Community
- Simula Labs Launches Hosted Delivery Platform To Enable Enterprise Open Source Adoption
- Where Are RIA Technologies Headed in 2008?
- Source Claims SCO Will Sue Google
- How Open Is "Open"? – Industry Luminaries Join the Debate
- Latest SCO News is Plain Weird
- IBM Tells SCO Court It Can't Find AIX-on-Power Code
- SCO Claims Linux Lifted ELF
- Flashback: Investing in 'Professional Open Source' - Exclusive 2004 Interview with David Skok, Matrix Partners
- HP Starts Pushing Desktop Linux
- Linux Business Week Exclusive: Linux Kernel To Be Re-Written To Counter Microsoft FUD






























