JVM Monitoring and Management Specificationby: Benoy Jose
Introduction:Application monitoring and profiling are a crucial part of any software system. Even if careful planning is done during design, architecture applications need to be monitored and profiled during QA testing and production to make sure that the performance of the application is optimal. There are a variety of third party products like JProbe from Quest software, Optimizeit from Borland and JPofiler from EJ Technologies which help in analyzing threads, monitor memory leaks and do other performance problems. IDEs like web sphere studios have built-in profiling tools which allow profiling and performance tuning during development. Most of tools in the market use the profiling API supplied with Java. Applications are usually comprised of different third party products and custom developed components required by the business. Application monitoring includes checking the overall health of the whole application and individually monitoring the performance of the individual components. This requires probes to be installed at each component to collect data related to these components. Finally all this data needs to be aggregated to ascertain the overall condition of the application. This collection process, though important, needs to be done non- intrusively so that the application is not affected. The current JVM specification does not provide any provision to monitor individual applications running within a JVM. The JSR 174 specification proposes guidelines and recommendations for an API that can help to monitor JVMs. The specification does not provide any interfaces to monitor JVMs nor will it define an abstract layer to do this job. It is primarily focused to define data that can be used to monitor and manage JVMs and also to provide guidelines for a native API. The job of providing the actual implementation will be left out to third party vendors who create monitoring tools.
Primary Features:The most important requirements of any monitoring model are listed below.
JVM Data:One of the important pieces of information required for any monitoring tools is the operating system information and the extent to which these operating system resources are used by the JVM. This becomes tricky as Java applications run on a variety of platforms and operating systems. Some of the mandatory operating system information required by monitoring applications is the operating system name, version and arch. Other JVM specific information that is mandatory is the VM name, version, vendor, specification version, specification name, Java class path, Java library path, etc. The specification proposes that the monitoring model use as much information as the operating system can provide and then it will add the platform specific extensions to get the other kinds of information required for monitoring. Apart from information from the JVM itself another source of monitoring data is the components within an application. Individual components can provide valuable information on threads, CPU utilization time, JIT compilation time, deadlock information etc. Information about these individual components may be difficult and expensive to retrieve, as these components may have varied implementations. Since these components usually run as separate threads on the JVM, data about these threads could be a good indicator of the performance of these components. Monitoring agents would require thread information like total number of threads created since the JVM started, current number of live threads, peak number of live threads, number of daemon threads, etc. Added to this is, specific information about the individual threads that can be used to know more about the application. Data like, Thread identifiers, thread state, the monitor the thread is blocked on, the thread that blocks the monitor, total number of contentions, and the thread stack trace can be used to identify deadlocks and thereby improve performance. One of the most important indicators of the health of the system is the memory usage. The JVM contains three memory pools and two memory managers to help in monitoring. One pool is for object allocation managed by a mark and sweep compact collector. The second one is for method area which is also managed by a mark and sweep compact collector. The third one is for native compiled code managed by a malloc/free manager. The first pool belongs to the heap memory and the rest of them belong to the non heap memory. The heap memory is a runtime data heap used by the JVM to store class instances and array objects. The memory in the heap is subject to automatic garbage collection by the garbage collector. The heap memory is defined by the JVM specification and will be uniform across multiple implementations of the JVM. However JVMs can use non heap memory to store data other than those stored in the heap. These can be runtime field and method data. Some JVM implementations can allocate resources on to the non heap memory to improve performance. These allocations are not specifically prohibited by the JVM specification. For the JVM the memory pools and memory managers are abstract entities. The JVM would at least have one memory pool and it can create or remove additional pools at runtime. In the same way the JVM can have one or more memory mangers and it has the ability to add or remove new memory mangers at runtime. The JVM can gather data about these memory pools and memory mangers and pass it on to the monitoring tool for analysis. Some of the information that the monitoring tool requires from the memory pool are the list of memory pools, size of the pool when it was initialized, size used, the size that is guaranteed by the JVM, and/or the maximum size of the pool. The memory manger should provide information of the name of the manager and the details of all the pools managed by the memory manager. Heap attributes required by the monitoring tools are the initial memory allocated on the heap, memory already used, maximum memory the JVM can use on the heap and more.
API Requirements:The API will have the ability to be used in a production environment with minimal intrusion. It will have access to all the mandatory data and the optional data discussed in the above section. The API will have on demand monitoring capability and will be pluggable without a restart of the system. The interface shall support multiple threads. The API shall provide the above mentioned facilities using JMX Mbeans. The API shall be extensible so that platform specific support can be provided.
Native Support:The sections above discussed the general requirements that any monitoring model has to support. The API also provides guidelines for a native interface that can be used to externalize the JVM monitoring data. Most of the time JVM data collected through monitoring is used internally for self monitoring the JVM. These are cases when this JVM data needs to be externalized so that JVMs can be monitored externally. Typical users are system administrators who would need this data to do continuous production monitoring. Other users could be IT support engineers who need the JVM data to troubleshoot problems in production and finally, development teams which require production data to enhance performance. The Monitoring API proposes a native interface to externalize the monitoring data discussed above. These interfaces can be defined by the utilizing the "self-describing extensions" defined in the JVM tools interface (JVMTI) outlined in the JSR 163. The native interface should support late binding of native agents without a JVM restart and connection to multiple agents and will help in the coordination of these multiple agents. They shall provide multi-thread safe operation. The native system shall provide facilities to monitor the life cycle of classes.
Related Specifications:
JVMTI:The Java Virtual Machine Tool Interface (JVMTI) is defined as part of the JSR 163 and is an API designed for developing tools for monitoring and development. It provides a mechanism to query the state of a JVM and control execution of applications running in a JVM. JVMTI can be used for profiling, debugging, monitoring and thread analysis to name a few. JVMTI can also help monitor events and then notify JVMTI client of any events they are registered to receive. The clients are usually thin and can be controlled by the same JVM or by a separate JVM. Tools can be directly written to the JVMTI or by using the high level interfaces defined by the API. The JVMTI is an extension of the Java Platform Debugger Architecture (JPDA).
JVMDIThe Java Virtual Machine Debug Interface (JVMDI) is a programming interface used by debuggers and other programming tools. JVMDI clients run in the same virtual machine in which the application being debugged is running and access JVMDI through a native interface. The native interface works with minimal intrusion on the part of a debugging tool. JVMDI describes the facilities provided by a JVM which can help in debugging the applications running under that JVM. JVMDI is one layer within the Java Platform Debugger Architecture (JPDA). The JPDA is briefly discussed below.
JPDA:The JPDA provides the infrastructure required for building debugger applications for the Java 2 Platform. JPDA is included in the J2SE 1.3 version. This API provides a standard interface to write debugging tools, irrespective of the platform, operating system and the JVM implementation.
Conclusion:The JVM Monitoring API is just a proposed guideline for third party tool developers to create monitoring tools. The API is not a self-contained specification for developing tools but uses relevant portions of the JVMTI so that details are not duplicated. Ultimately the API would go as part of the JSR 163 where general specifications for tool developing would be defined.
Benoy Jose is a web developer with over six years of experience in J2EE and Microsoft technologies. He is a Sun Cetified programmer and enjoys writing technical and non-technical articles for various magazines.
|