The example in this section shows how you can run the profiler that ships with the JDK. Although the information from this profiler is in the somewhat crude form of text files rather than the graphical representation that most commercial profilers produce, it still provides valuable help in determining the characteristics of your program.
You run the profiler by passing an extra argument to the JVM when you invoke the program. This argument must be a single string, without any spaces after the commas, like this (although it should be on a single line, it has wrapped in the book):
java –Xrunhprof:heap=sites,cpu=samples,depth=10,monitor=y,thread=y,doe=y ListPerformance
- The heap=sites tells the profiler to write information about memory
utilization on the heap, indicating where it was allocated.
- cpu=samples tells the profiler to do statistical sampling to
determine CPU use.
- depth=10 indicates the depth of the trace for threads.
- thread=y tells the profiler to identify the threads in the stack
- doe=y tells the profiler to produce dump of profiling data on
The following listing contains only a portion of the file produced by HPROF. The output file is created in the current directory and is named java.hprof.txt.
The beginning of java.hprof.txt describes the details of the remaining sections in the file. The data produced by the profiler is in different sections; for example, TRACE represents a trace section in the file. You will see many TRACE sections, each numbered so that they can be referenced later.
The SITES section shows memory allocation sites. The section has several rows, sorted by the number of bytes that are allocated and are being referenced—the live bytes. The memory is listed in bytes. The column self represents the percentage of memory taken up by this site, the next column, accum, represents the cumulative memory percentage. The live bytes and live objects columns represent the number of live bytes at this site and the number of objects that were created that consumes these bytes. The allocated bytes and objects represent the total number of objects and bytes that are instantiated, including the ones being used and the ones not being used. The difference in the number of bytes listed in allocated and live represent the bytes that can be garbage collected. The trace column actually references a TRACE in the file. The first row references trace 668 as shown below. The name represents the class whose instance was created.
SITES BEGIN (ordered by live bytes) Thu Jul 18 11:23:06 2002
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 59.10% 59.10% 573488 3 573488 3 668 java.lang.Object
2 7.41% 66.50% 71880 543 72624 559 1 [C
3 7.39% 73.89% 71728 3 82000 10 649 java.lang.Object
4 5.14% 79.03% 49896 232 49896 232 1 [B
5 2.53% 81.57% 24592 310 24592 310 1 [S
TRACE 668: (thread=1)
This trace shows the method call sequence that allocates the memory. If you go through the trace as indicated by the line numbers, you will find that an object allocation takes place on line number 222 of Vector.java:
elementData = new Object[newCapacity];
This helps you discover parts of the program that use up significant amounts of memory (59.10 %, in this case).
Note the [C in SITE 1 represents the primitive type char. This is the internal representation of the JVM for the primitive types.