Monitoring the Java Virtual Machine

Java Management Extensions (JMX) provide tools for monitoring and managing applications and the resources they use.


April 01, 2006
URL:http://www.drdobbs.com/jvm/monitoring-the-java-virtual-machine/184406481

Paul is a senior software developer at Vonage. He can be contacted at [email protected].


Java Management Extensions (JMX) technology provides tools for monitoring and managing applications and the resources they use. In this article, I examine how Java 5 carries monitoring and management technology to the next level by instrumenting the Java Virtual Machine itself, thus providing the tools you can use to monitor its functional components.

While MBeans aren't new (see my article "Java Management Extensions," DDJ, July 2004), Java 5 does include a new package called "java.lang.management" that defines nine special MBeans called "platform MBeans" or "MXBeans." Each of these MXBeans (see Table 1) encapsulates a single functional area of the VM. Like all MBeans, each MXBean has a unique javax.management.ObjectName. For MXBeans, the name takes the form java.lang:type=ttt where ttt is a string formed by dropping the trailing "MXBean" from the interface name in column 1 of Table 1.

MBeans are not accessed directly by an application. They reside in—and are managed by—a repository called an "MBean server," which implements the interface javax.management.MBeanServer. Java 5 features a special MBean server called the "platform MBean server," which is built into the VM. Platform MBeans are registered in this server using their unique names.

You access the platform MBean server by invoking the static getPlatformMBeanServer method of the java.lang.management.ManagementFactory class. Examine ListMBeans (available at www.ddj.com/code/ddj.html) and you see this code:

MBeanServer mbs =
ManagementFactory.getPlatformMBeanServer();

which obtains a reference to the platform MBean server.

The displaySortedBeanList() method in ListMBeans uses the MBeanServer's queryNames() method to get the names of the MBeans controlled by the server. It sorts the list and displays it. If you examine the output from the program (Figure 1), you can see that the list includes each of the MXBeans in Table 1. You probably also noticed that Figure 1 displays a list of 18 MBeans followed by a second list of 19 MBeans. The additional MBean in the second list, which has the unique identifier ca.tremblett.ddj:name=My MBean, is an instance of MyMBean (available at http://www.ddj.com/code/ddj.html). To see where it was registered in the MBean server, examine the registerMBean() method of ListMBeans. The fact that ListMBeans can register an MBean demonstrates that the MBeans managed by the platform MBean server are not limited to those that are registered by the VM. Furthermore, because there is usually no need for more than a single MBean server, I suggest you use the platform MBean server unless you have a good reason to create your own using the MBeanServerFactory class.

If you examine the javadocs for the interfaces in Table 1, you find more than 50 getter methods. You can use the information returned by these methods to make a detailed assessment of the state of the virtual machine at any point during the execution of your application. The program MXBDemo1 (available electronically) shows how to use some of the getter methods. Notice that the platform MBeans are obtained using static methods of the ManagementFactory class. Figure 2 is output from the program.

In addition to the getter methods, some of the management interfaces define setter methods that you can use to control the behavior of the VM. Say your application is using Class.forName(someClassName).newInstance() and you are encountering what you suspect might be a problem related to the class loader. You could run the program using the VM argument -verbose:class, but you would be faced with the task of sorting through a potentially large volume of output. A better approach would be to obtain the ClassLoadingMXBean, invoke its setVerbose(true) method just before you create your instance followed by setVerbose(false) immediately following the code you are attempting to debug. This is demonstrated in MXBDemo2 (available at www.ddj.com/code/ddj.html). When you run this program, it produces the output shown in Figure 3. Notice that verbose output is generated only for the third class that is instantiated.

A Practical Use of Platform Beans

Suppose you are developing an application that will create some number of worker threads and you are faced with the issue of how to set a limit to that number of threads so as not to exhaust all available heap memory. One approach might be to pass the number to the application as a command-line argument or as a property in a properties file. In either case, the number you choose tends to be arbitrary or a best guess. A better approach might be to use runtime data you obtain from platform MBeans to determine the number of threads.

Take a look at MXBDemo3 (available at www.ddj.com/code/ddj.html). It starts by scheduling a TimerTask that displays garbage collection statistics and memory usage every 30 seconds. It then enters a while loop that creates and starts threads for a maximum of 30 seconds. Before it creates a thread, however, the program determines the amount of available heap memory. If the heap is more than 50 percent utilized, it defers creating the thread. After the maximum possible number of threads have been started, the program waits until all threads have completed, and then exits. To minimize the number of threads that the program creates and the volume of output it produces before it completes, the VM arguments -Xms1m and -Xmx2m (1-MB initial heap size, 2-MB maximum heap size) are specified.

Admittedly, the example is contrived and its simple logic would prove inadequate for real-world use; however, it should suffice to demonstrate how you can use platform MBeans.

Conclusion

Each generation of the Java platform delivers new functionality that results in the development of better applications. The introduction of platform MBeans and the platform MBean server in Java 5 is proof.

DDJ

April, 2006: Monitoring the Java Virtual Machine

server is managing 18MBeans
JMImplementation:type=MBeanServerDelegate
java.lang:name=Code Cache,type=MemoryPool
java.lang:name=
   CodeCacheManager,type=MemoryManager
java.lang:name=Copy,type=GarbageCollector
java.lang:name=Eden Space,type=MemoryPool
java.lang:name=
   MarkSweepCompact,type=GarbageCollector
java.lang:name=
   Perm Gen [shared-ro],type=MemoryPool
java.lang:name=
   Perm Gen [shared-rw],type=MemoryPool
java.lang:name=Perm Gen,type=MemoryPool
java.lang:name=Survivor Space,type=MemoryPool
java.lang:name=Tenured Gen,type=MemoryPool
java.lang:type=ClassLoading
java.lang:type=Compilation
java.lang:type=Memory
java.lang:type=OperatingSystem
java.lang:type=Runtime
java.lang:type=Threading
java.util.logging:type=Logging

Registering simple MBean

server is managing 19MBeans
JMImplementation:type=MBeanServerDelegate
ca.tremblett.ddj:name=My MBean
java.lang:name=Code Cache,type=MemoryPool
java.lang:name
   =CodeCacheManager,type=MemoryManager
java.lang:name=Copy,type=GarbageCollector
java.lang:name=Eden Space,type=MemoryPool
java.lang:name=
   MarkSweepCompact,type=GarbageCollector
java.lang:name=
   Perm Gen [shared-ro],type=MemoryPool
java.lang:name=
   Perm Gen [shared-rw],type=MemoryPool
java.lang:name=Perm Gen,type=MemoryPool
java.lang:name=Survivor Space,type=MemoryPool
java.lang:name=Tenured Gen,type=MemoryPool
java.lang:type=ClassLoading
java.lang:type=Compilation
java.lang:type=Memory
java.lang:type=OperatingSystem
java.lang:type=Runtime
java.lang:type=Threading
java.util.logging:type=Logging

Figure 1: Output from the ListMBeans program.

April, 2006: Monitoring the Java Virtual Machine

OPERATING SYSTEM:
	architecture = ppc
	name = Mac OS X
	version = 10.4.3
	processors = 1

RUNTIME:
	name = [email protected]
	spec name = Java Virtual Machine Specification
	vendor = Sun Microsystems Inc.
	spec version = 1.0
	management spec version = 1.0

CLASS LOADING SYSTEM:
	isVerbose = false
	loadedClassCount = 371
	totalLoadedClassCount = 371
	unloadedClassCount = 0

COMPILATION
	totalCompilationTime = 150

MEMORY:
HEAP STORAGE:
	committed = 2031616
	init = 0
	max = 66387968
	used = 399648
NON_HEAP STORAGE
	committed = 30113792
	init = 29523968
	max = 121634816
	used = 11508000
	name: Code Cache
	Manager Name: CodeCacheManager
	mtype = Non-heap memory
	Usage threshold supported = true
	name: Eden Space
	Manager Name: MarkSweepCompact
	Manager Name: Copy
	mtype = Heap memory
	Usage threshold supported = false
	name: Survivor Space
	Manager Name: MarkSweepCompact
	Manager Name: Copy
	mtype = Heap memory
	Usage threshold supported = false
	name: Tenured Gen
	Manager Name: MarkSweepCompact
	mtype = Heap memory
	Usage threshold supported = true
	name: Perm Gen
	Manager Name: MarkSweepCompact
	mtype = Non-heap memory
	Usage threshold supported = true
	name: Perm Gen [shared-ro]
	Manager Name: MarkSweepCompact
	mtype = Non-heap memory
	Usage threshold supported = true
	name: Perm Gen [shared-rw]
	Manager Name: MarkSweepCompact
	mtype = Non-heap memory
	Usage threshold supported = true

THREADS:
	Thread name = Signal Dispatcher
	Thread name = Finalizer
	Thread name = Reference Handler
	Thread name = main
GARBAGE COLLECTION:
	name = Copy
	collection count = 0
	collection time = 0
	mpool name = Eden Space
	mpool name = Survivor Space
	name = MarkSweepCompact
	collection count = 0
	collection time = 0
	mpool name = Eden Space
	mpool name = Survivor Space
	mpool name = Tenured Gen
	mpool name = Perm Gen
	mpool name = Perm Gen [shared-ro]
	mpool name = Perm Gen [shared-rw]

Figure 2: Output from the MXBDemo1 program.

April, 2006: Monitoring the Java Virtual Machine

creating instance of ArrayList
creating instance of Date
Enabling verbose output
creating instance of GregorianCalendar
[Loaded java.util.Calendar from shared objects file]
[Loaded java.util.GregorianCalendar from shared objects file]
creating instance of Hashtable

Figure 3: Output from the MXBDemo2 program.

April, 2006: Monitoring the Java Virtual Machine

Interface Manages Instances per VM
ClassLoadingMXBean Class loading system 1
CompilationMXBean Compilation system 0 or 1
GarbageCollectorMXBean Garbage collector > 1
MemoryManagerMXBean Memory pool > 1
MemoryPoolMXBean Memory > 1
MemoryMXBean Memory system 1
OperatingSystemMXBean Operating system 1
RuntimeMXBean Runtime system 1
ThreadMXBean Thread system 1

Table 1: MXBeans.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.