This article is based on The Well-Grounded Java Developer, to be published Summer-2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]
VisualVM in Oracle JVM
VisualVM is a visualization tool that ships with the standard Oracle JVM. It has plugin architecture and, in one standard configuration, can be used as a more convenient replacement for the now venerable JConsole. In figure 1, we show a standard VisualVM summary screen.
Figure 1 VisualVM application summary screen There are a lot of useful tabs across the top of the right-hand panel. We run with the Extensions, Sampler, JConsole, MBeans, and VisualVM plugins, which makes up an excellent toolset for really getting to grips with some of the dynamic aspects of the Java runtime. We recommend installing all of the above plugins into VisualVM before doing any serious work with it.
There are several important things to notice in figure 2—first is the “saw tooth” pattern of memory utilization. This is an absolutely classic visualization of how memory is used in the Java platform. It represents objects being allocated in Eden, used, and then collected in young collections.
Figure 2 VisualVM overview screen After each young collection, the amount of memory used falls back to a baseline level. This level is the combined usage of the objects in tenured and survivor. It can be used to ascertain the health of a Java process over time. If the baseline stays stable (or even decreases over time) while the process is working, then the memory utilization should be very healthy.
If the baseline level rises, then this does not necessarily mean that anything is necessarily wrong—just that some objects are living long enough to reach tenure. In this case, a full collection will eventually occur. The full collections will lead to a second “saw tooth” pattern—with the memory used falling back to a baseline corresponding to the level that has only truly live objects in memory. If the full collection baseline is stable over time, then the process should not run out of memory.
One key concept is that the gradient of the slope on the saw teeth is the rate at which a process is using young generation (usually Eden) memory. So, the aim of reducing the amount of young collections is basically trying to reduce the steepness of the saw teeth.
Another way of visualizing the running memory usage is shown in figure 3—here, we can see Eden, the Survivor spaces (S0 and S1), and the Old and Perm generations. As the application runs, we can see the sizes of the generations change. In particular, after a young collection, we will see Eden shrink, and the Survivor spaces swap roles.
Figure 3 VisualVM’s VisualGC plugin Exploring the memory system and other aspects of the runtime environment will help you understand how your code runs. This, in turn, shows how the services that the VM provides impact performance—so it’s definitely worth taking time to experiment with VisualVM, especially in combination with switches such as Xmx and Xms.
Automatic memory management is one of the most important parts of the Java platform. Before managed platforms such as Java and .NET, the average developer could expect to spend a noticeable percentage of their career hunting down bugs caused by imperfect memory handling.
In recent years, however, automatic allocation techniques have become so advanced and reliable that they have become part of the furniture—a large number of Java developers are unaware of how the memory management capabilities of the platform work, what options are available to the developer, and how to optimize within the constraints of the framework. In this article, we discussed VisualVM, a visualization tool available through standard Oracle JVM.