By user12820862 on Nov 20, 2005
I was in New York last week, and attended a Java SE User Group meeting. After the scheduled talks there was open discussion on a wide range of topics. One of those topics related to tutorials, documentation, and sample code. It is always interesting to hear how people learn new APIs. Some people start with the API documentation, some google for sample code, and books continue to be popular. The JDK "demo" directory was mentioned and a number of people remarked that they hadn't checked it out in years because the demo directory appeared to be stale. There are indeed some old demos in there but there are a number of more recent examples too. Today I thought I might highlight two of the more useful examples.
The first is JTop. You'll find it in %JDK_HOME%\\demo\\management\\JTop (or $JDK_HOME/demo/management/JTop) where JDK_HOME is C:\\jdk1.6 or wherever you have installed the JDK. Mandy Chung added this demo in Mustang b59 and it will work on JDK5.0 too. There's a README.txt file in the directory which explains what it does. In brief, it monitors the CPU usage of the threads in a remote application. If you've ever had to deal with a looping process and you tried to figure out which thread is looping then you will relate to this.
In API terms, this example is a demonstration of the monitoring and management package. If the Java virtual machine is able to measure thread CPU time then getThreadCpuTime method can be used to obtain the CPU time for a thread.
To use JTop, we start the application with the JMX agent configured for remote management. For demonstration purposes both authentication and SSL are disabled (which you won't want to do in production).
java -Dcom.sun.management.jmxremote.port=7000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar Application.jar
JTop is connected by passing it the hostname and port number so that it can connect to the JMX agent:
java -jar %JDK_HOME%\\demo\\management\\JTop\\JTop.jar localhost:7000
JTop uses a TimerTask to refresh the thread list every 2 seconds. It gets the CPU time for each thread and then sorts the list by CPU time. You should see something like this:
It is primitive but it serves as a useful demonstration of the APIs. The source is in the src directory and with a little bit of effort it could be turned into a nice tool. For example, it currently just sorts the threads by total CPU usage and it might be nicer to highlight the threads that were busy in the proceeding interval. Also, it might be interesting to sample the stack traces of the busy threads to get an idea of the code that is executing.
The second example is heapViewer. You'll find it in %JDK_HOME%\\demo\\jvmti\\heapViewer (or $JDK_HOME/demo/jvmti/heapViewer). This example has been included since JDK5.0. It's a native agent that uses the JVM Tool Interface to do some basic memory analysis. It uses IterateOverHeap to do a linear iteration over all objects in the heap. It then prints a summary in the form of a class-wise histogram to show which objects are taking up space in the heap.
The agent is an in-process agent that is started using the -agentlib or -agentpath command-line options. Here's one example:
java -agentpath:%JDK_HOME%\\demo\\jvmti\\heapViewer\\lib\\heapViewer.dll -jar Application.jar
When the VM exits or the agent gets a DataDumpRequest event then it will print a histogram to summarize the objects in the heap. A DataDumpRequest is triggered by a Ctrl-Break on Windows, or Ctrl-\\ (or SIGQUIT) on Solaris/Linux. Here is some sample output:
Heap View, Total of 123199 objects found. Space Count Class Signature ---------- ---------- ---------------------- 19597872 7421 [I 1420264 13037 [C 1217872 2681 [B 1194256 2381 Ljava/lang/Class; 985624 3619 [S 266688 11112 Ljava/lang/String; 173576 4682 [Ljava/lang/Object; 164800 824 Lsun/java2d/SunGraphics2D; 123888 5162 Ljava/util/Hashtable$Entry; 106560 4440 Ljava/awt/Rectangle; 79552 2486 Ljavax/swing/text/html/parser/ContentModel; 70816 818 [Ljava/util/Hashtable$Entry; 67440 843 Ljavax/swing/text/html/InlineView; 63504 2646 Ljavax/swing/SizeRequirements; 57984 906 Ljava/awt/geom/AffineTransform; 56600 1415 Ljava/util/WeakHashMap$Entry; 55560 2315 Ljava/util/HashMap$Entry; 52864 112 Ljavax/swing/plaf/metal/MetalScrollButton; 46880 2930 Ljavax/swing/event/EventListenerList; 45056 352 Ljavax/swing/text/html/LineView; 44808 1867 Ljava/awt/Insets; ---------- ---------- ----------------------
In this example, there were 123199 objects in the heap, and integer arrays are taking up the most space. There are of course other ways to generate a heap histogram like this but this one is useful as it makes use of the standard APIs. The source for this example is in the src directory.
I hope you agree these are useful examples. There are a number of others in the demo/management and demo/jvmti directories which are worth checking out too.