Microsoft Corporation
January 1999
Introduction
New Features at a Glance
The Java Profiler API
The Java Heap Monitoring API
The Java Debug API
Microsoft Technologies at Work
Sources for Additional Information
Compared to a decade ago, the software development process has become much more complex. In the past, many applications were written as simple stand-alone programs for handling a specific task; now the requirements are for integration between applications. The desktop has matured with the introduction of Microsoft® Windows NT®, Microsoft® Windows® 95, and Microsoft® Windows® 98. New applications targeting these Win32® operating systems are capable of replacing enterprise applications that once ran on UNIX RISC machines and IBM mainframes. Consequently, the need for powerful and robust software development tools has never been greater.
The Java language is receiving wide acceptance by software developers and tool vendors. Compared to C++ and other object-oriented languages, Java is easier to learn, and new programmers can become productive sooner. A number of industry studies have found that applications written in Java can be completed in half the time required with C++. The Java language has the potential to displace other object-oriented languages and become dominant on the Web and in other general business applications.
The Java language leaves out many features found in C and C++ that often introduce errors into programs. The runtime environment provided by the Microsoft virtual machine (Microsoft VM) eliminates pointers and uses automatic garbage collection for managing memory, thus freeing the programmer from these error-prone areas. However, the runtime features needed to provide these benefits also impose a performance penalty each time the program is run. Consequently, there is strong interest in the market for Java profiling and memory-monitoring tools designed to identify potential performance issues.
Although developers may become productive faster using Java, programming errors still occur. In particular, the use of multithreading and other concurrency issues can introduce errors that are difficult to find. While Java may reduce certain classes of errors, developing robust applications for the enterprise or for personal productivity still requires the use of tools for debugging and testing applications.
Microsoft has a strong commitment to Java. The Microsoft VM continues to win awards and accolades as the fastest runtime implementation of Java on Win32 platforms. The Microsoft VM provides a variety of APIs that give software developers and tool vendors access to its underlying features. These features are especially useful for creating powerful Java development tools to use with the Microsoft VM. In particular, the most recent releases of the Microsoft VM add a rich set of APIs for profiling, monitoring memory and events, and debugging applications written in Java or in a mixture of Java and other languages.
The Microsoft VM provides developers with a rich environment for writing powerful and sophisticated tools for profiling and debugging Java applications. The Microsoft VM exposes these features as a series of Component Object Model (COM) objects, so they can be used from any programming language that supports COM. This same flexibility provides developers with the ability to create tools that can be distributed across networked computers using Distributed COM (DCOM). The Microsoft VM also supports using these features with Just-In-Time (JIT) compiled Java code.
Performance is often an issue with applications, including those written in Java. The Microsoft VM supports a set of Java profiler interfaces to assist in the analysis of Java code for speed, memory use, and other performance factors. The profiler interfaces support any number of concurrently operating profilers and event monitors for gathering information on execution times, events, and memory usage. These interfaces can also profile components that mix Java classes with Win32 native code.
Some of the key features in the Microsoft VM designed for execution profiling include the following:
Although Java supports automatic garbage collection, understanding how memory is used in a Java application or applet can be an important part of improving performance. The Microsoft VM includes a powerful set of Java heap monitoring interfaces that allow an application to collect detailed information on heap memory usage and garbage collection activity for a Java application or applet.
New features for supporting heap monitoring include the following:
The debugger interfaces assist in the detection, location, and correction of logical errors in Java applications, applets, and COM objects that are run in the Microsoft VM. The debugger interfaces can handle a mixture of JIT-compiled methods and interpreted Java code.
New features in the Microsoft VM to support debugging include the following:
All of these profiling and debugging features are incorporated in the Microsoft VM that ships with Microsoft Internet Explorer 4.01 or later, Visual J++®, Windows 95, Windows 98, Windows NT, and many other Microsoft products. No special software is required to take advantage of these powerful features.
Complete documentation and code samples describing the use of these Java profiler and debugger interfaces are provided in the Microsoft SDK for Java. The SDK for Java is free and can be downloaded from the following location:
http://www.microsoft.com/java/ .
The Java profiler interfaces provide a powerful framework for analyzing Java code performance for speed and heap memory use. The profiler interfaces are implemented as COM objects by the Microsoft VM. This allows these interfaces to be used from Java, Visual C++®, Visual Basic®, or any other programming language that supports COM calling conventions.
The profiler interfaces used by the Microsoft VM can be organized into categories as shown in the following table.
Category | Purpose |
Event monitor information | The interfaces called by the profiler to set event masks and request specific information from the Microsoft VM when events occur. |
Event notification | The callback interfaces implemented by the profiler through which the Microsoft VM notifies the profiler of various events and returns the requested information. |
Heap monitor information | The interface called by the profiler to request information from the Microsoft VM regarding heap memory usage of the Java application or applet. |
Heap monitor notification | The callback interfaces that must be implemented by the profiler through which the Microsoft VM notifies the profiler of various memory and object allocation information. |
A profiler or event monitor must register itself on the local machine so that it can be started by the Microsoft VM when a Java process begins execution. A profiler calls methods on COM objects implemented by the Microsoft VM to request event notifications and specific information from the Microsoft VM when events occur. Communication from the Microsoft VM to the profiler is based on sending event notifications to the profiler. The profiler implements these callback routines as methods on COM objects. These event notifications inform the profiler of various activities occurring in the Microsoft VM on behalf of the Java application or applet being profiled.
The categories of event types that can be monitored include those in the following table.
Event category | Description |
Bytecode instruction execution | Send event notification when a Java bytecode instruction is about to be executed. |
Class loading and unloading | Send event notification when a Java class is about to be loaded or unloaded. |
Exceptions | Send event notification when an exception is about to be thrown. |
Garbage collection | Send event notification when the Microsoft VM is about to execute and has completed a garbage collection. |
JIT method compilation | Send event notification when a Java method is about to be JIT-compiled and after JIT compilation is complete. |
Method calls | Send event notification when a class method is about to be called and upon completion of the method call. |
Object monitor operations | Send event notification when a Java object monitor (synchronization object) operation is about to be executed. |
Source line execution | Send event notification when a Java source line is about to be executed. |
Track specific method calls | Send event notification when specific Java methods are called. This feature allows a profiler to restrict the methods it is interested in. |
Thread creation and destruction | Send event notification when a Java thread is created or destroyed, or when the name of a Java thread has been set. |
The profiler COM interfaces implemented by the Microsoft VM use the in-process free-threading model. Events are dispatched from within the VM on the thread that caused the event. Interface methods implemented by the VM can be called any time from any thread that has been properly initialized. These features simplify developing profilers with any language supporting COM.
The heap monitoring interfaces allow a memory profiler to collect detailed information on heap memory usage and garbage collection activity for a Java process. The heap monitoring interfaces allow a memory profiler to receive notification on each object allocation, to track when garbage collections occur, and to retrieve a detailed heap dump after garbage collection.
The heap monitoring interfaces are implemented by the Microsoft VM as COM objects. A memory profiler calls methods on COM objects implemented by the Microsoft VM to request information from the Microsoft VM regarding heap memory usage of the Java application or applet. A memory profiler must implement its callback routines as COM objects. Heap monitoring follows a conceptual model similar to the other profiler interfaces. A memory profiler must register with the Microsoft VM, indicating an interest in receiving notifications for heap monitoring, and register its heap information callback interface. The Microsoft VM will communicate with the memory profiler through this callback interface.
The heap monitoring interfaces make extensive use of the concept of containers for representing heap usage. Through these containers, a memory profiler can completely rebuild the containment hierarchy for heap memory starting from root containers. Container types are defined for threads, static class references, objects awaiting finalization, internal Microsoft VM objects, and various stack frames (native garbage collection, JIT-compiled methods, native methods, COM methods, interpreted methods, and fast-interpreted methods).
The heap is presented to the memory profiler in a depth-first traversal. Profilers may optionally select to abort traversal of certain branches or from uninteresting roots, enabling control over which portions of the heap are traversed. Additional traversals may be requested to enable searches or other multiple-pass operations.
The heap monitoring COM interfaces implemented by the Microsoft VM use the in-process free-threading model, like the other profiler interfaces.
The debugger interfaces provide a powerful framework for locating errors in Java applications, applets, and Java-implemented COM objects that are run in the Microsoft VM. These interfaces can also be used for debugging Java code that mixes Java classes with COM objects and native Win32 code.
The debugger interfaces are implemented in the Microsoft VM as COM objects. A debugger communicates with the Microsoft VM, requesting information and controlling the Java execution environment by calling methods on these COM objects. Similarly, the Microsoft VM notifies the debugger of events and provides requested information to the debugger by calling methods on COM objects that the debugger implements as callback routines. These debugger interfaces can easily be extended to allow remote debugging using DCOM. Debuggers can also be written in Java using a set of Java classes in the com.ms.debug package supplied with the Microsoft SDK for Java. These Java classes provide wrapped COM interfaces to the Java Debug API.
The Java debugger interfaces used by the Microsoft VM can be organized into several categories, as shown in the following table.
Category | Purpose |
Registration interfaces | The interfaces called by a debugger to register with the Microsoft VM and that request to be notified when specific events occur. |
Notification interfaces | The callback interfaces implemented by the debugger through which the Microsoft VM notifies the debugger of various events and then returns the requested information. |
Static information interfaces | The interfaces called by a debugger to request static information about Java classes. |
Dynamic information interfaces | The interfaces called by a debugger to request dynamic information about a Java process during execution. |
Execution control interfaces | The interfaces called by a debugger to control the execution of a Java process. |
To use the debugger interfaces, a debugger calls methods of the registration interfaces implemented by the Microsoft VM. A debugger can request to be informed of new Java processes that are created. A debugger can also call methods implemented by the Microsoft VM to enumerate all Java processes currently running. After a debugger attaches to a Java process, it will be notified of a variety of events. The Microsoft VM calls methods on the COM interfaces implemented by the debugger to communicate these notifications.
A debugger can receive notifications from the Microsoft VM as shown in the following table.
Method | Description when notification occurs |
BreakEvent | When an asynchronous break occurs. An asynchronous break may be requested by the debugger. A break can also be caused by the application or applet calling com.ms.debug.Debugger.breakpoint. |
CanStopEvent | During a range step when the Java process being debugged makes a function call, or the method in which stepping was initiated returns. |
ClassLoadEvent | When a Java class is loaded. |
ClassUnloadEvent | When a Java class is unloaded. |
CodeBreakPointEvent | When a code breakpoint is hit by the Java process being debugged. |
DataBreakPointEvent | When a data breakpoint (a watchpoint) is hit by the Java process being debugged. |
DebugStringEvent | When the Java process being debugged outputs a string to the debugger. An application being debugged may produce output for the debugger by using the com.ms.debug.Debugger class. |
ExceptionEvent | When an exception occurs in the Java process being debugged. |
LoadCompleteEvent | When notifications have been sent for all Java classes loaded before the debugger attached. |
ProcessDestroyEvent | When a Java process terminates. |
StartClassEvent | Notifies the debugger of classes that caused the Microsoft VM to be loaded, such as Java-implemented COM objects, or the class containing the main method for Java applications. |
StepEvent | When an execution step is complete in the Java process being debugged. |
ThreadCreateEvent | When a thread is created. |
ThreadDestroyEvent | When a thread is destroyed. |
ThreadGroupCreateEvent | When a thread group is created. |
ThreadGroupDestroyEvent | When a thread group is destroyed. |
Static information on the classes used in a Java process is available through a hierarchy of IRemoteField interfaces. These interfaces allow the debugger to navigate from Java classes to the methods, interfaces, inner classes, and fields of the class as well as to the superclass. These interfaces also provide methods for setting code breakpoints, clearing breakpoints, and retrieving Java method bytecodes. Because many attributes of a class are constant while the class is being loaded, this information can be cached by the debugger.
Dynamic information on a Java process is available through a hierarchy of IRemoteObject interfaces. These interfaces provide bound run-time access to objects of different types. An IRemoteObject does not necessarily refer to an instance of a class, but represents an instance of any data type. These interfaces implement methods used to get the type of an object, get or set the value of an object, and set or clear data breakpoints on the object. A data breakpoint will fire when the value of the associated object changes. The information obtained from an IRemoteObject is only valid during the lifetime of the underlying Java object that it represents. IRemoteObjects may be held across execution and re-evaluated when needed.
Monitoring execution of a Java process is possible through the IRemoteThread and IRemoteStackFrame interfaces implemented by the Microsoft VM. Methods on the IRemoteThread interface allow a debugger to suspend or resume execution of a thread, step within a method, step into, over, or out of a call to a method, and get the stack frames on a thread. The IRemoteStackFrame interface provides access to the Java method call stacks of the threads executing in the Java process being debugged. Each stack frame represents a method's state of execution. Stack frame interfaces maintain their identity across the execution of the application or applet being debugged.
The debugger COM interfaces use the apartment-threading model. The Microsoft VM uses a single apartment thread to dispatch all debugger events in order to simplify the debugger's task by serializing event notifications.
Java technologies are used by Microsoft in several of its own development tools. Visual J++ leverages these features to provide the powerful Java debugger included with this Java-integrated development environment. The command-line debugger included with the Microsoft SDK for Java also uses these Java debugger interfaces.
A number of leading-edge technology companies are already using the Java profiler and debugger APIs to advantage in shipping products. These companies and products include the following:
By taking advantage of the Java profiler and debugger technologies included with the Microsoft VM, these companies are able to offer some of the most powerful tools for Java developers. Other companies have plans to leverage these Microsoft technologies as well.
The Java language is being used to develop a variety of applications for the enterprise and for personal productivity. Programmers and software development teams are demanding more powerful and feature-rich development tools from vendors. As the market for Java development increases, the opportunity expands for new tools that target the varying needs of software development. The profiler and debugger technologies included with the Microsoft VM represent some of the many ways that Microsoft is offering a framework for leading-edge development using Java.