|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON Integration Walking the Java Heap with NetBeans 6.0 Profiler
Pre-crisis quality control
By: Tim Boudreau
Jan. 20, 2008 11:00 AM
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 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 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 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 LATEST JAVA STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK SPONSORED BY INFRAGISTICS
BREAKING JAVA NEWS
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||