
Technical Information
Debugging and Profiling Java Applications
|
 |
|
Microsoft Corporation
January 1999
Download this document in Microsoft Word format (zipped, 20 KB)
Contents
Introduction
New Features at a Glance
The Java Profiler API
The Java Heap Monitoring API
The Java Debug API
Microsoft Technologies at Work
Introduction
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++1. The Java language has the potential to displace other object-oriented languages and become dominant on the Web and in other general business applications.
1 Quinn, Evan; Chris Christiansen, "Java Pays - Positively: bulletin," International Data Corporation Report no. 16212, June 1998: 5, 28.
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 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.
New Features at a Glance
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:
- Multiple profilers can operate concurrently.
- Profiling capabilities are easily customized using
environment variables or registry settings.
- Developers have detailed control over the types of events to
be monitored.
- Improvements for sampling profilers provide greater control
and accuracy.
- Object monitor operations can be monitored.
- Static class information is available for Java classes.
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:
- Profilers can receive notifications on each heap object
allocation.
- The occurrence and duration of garbage collections can be
tracked.
- Profilers can determine the number of garbage collections an
object survives.
- A detailed heap dump can be retrieved after garbage
collection occurs.
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:
- Debugging capabilities are easily customized using
environment variables or registry settings.
- Debugging both interpreted and JIT-compiled code is
supported.
- Debuggers can be attached to a Java process that is already
running (JIT debugging).
- Complete access is provided to static information on Java
classes.
- Detailed access is available to dynamic information on Java
class fields, local variables in methods, arrays, and other data
types.
- Breakpoints can be set on data access (watchpoints) as well
as on code execution.
- Complete support is available for thread groups and
threads.
- Java inner classes can be debugged.
- Improvements are available to support mixed-language
debugging.
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: www.microsoft.com/java/
The Java Profiler API
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. |
Back to Top
The Java Heap Monitoring API
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.
Back to Top
The Java Debug API
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.
Back to Top
Microsoft Technologies at Work
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:
- Intel VTune profiler
- Rational Software Quantify profiler
- Compuware (formerly NuMega Technologies) TrueTime
profiler
- Sybase PowerJ Java integrated development
environment
- SilverStream Application Server
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.
|