− mpegaudio: an MP3 audio stream decoder; − mtrt: a dual-threaded program that ray traces an image file; − jack: a parser generator with lexical analysis;
We ran SPEC JVM98 on a Linux Fedora Core 2 computer (Intel Pentium 4, 2.6 GHz, 512 MB RAM). For all experiments, the entire JVM98 benchmark suite was run 40 times. Then, for each program, the median execution time was used to compute the slowdown ratio (i.e., the overhead) compared to the original, unmodified version of the pro- gram. Finally, a global overhead indicator was obtained by calculating the geometric mean of these ratios. All executions are automatically verified for semantic correctness by the SPEC JVM98 benchmark suite itself, by comparing actual output with expected data. It should be noted that with this setup our execution time measurements have a remaining imprecision of 1%,9 although the test machine is each time restarted and booted into a mode with only the strictly necessary system services active.
Measurements were made on the IBM JDK 1.4.2 platform in its default execution mode only, as well as the Sun JDK 1.5.0 platform in its following three modes:
Purely interpreted mode (-Xint command-line option): this com- pletely deactivates the just-in-time (JIT) compiler, and gives us an idea of how the relative overheads and consecutive optimizations might manifest themselves in a primitive Java environment, such as on certain embedded systems with limited resources.
Client mode (-client command-line option): this starts the Sun Java HotSpot  Client VM, which is tuned for reducing start- up time and memory footprint, and has a JIT that incrementally compiles bytecodes into native instructions.
3. Server mode (-server command-line option): this launches the Sun Java HotSpot Server VM, which is designed for maximum program execution speed and therefore contains a JIT that optimizes code more systematically at load-time.
All other JVM-specific options take their default values. In our test we used a single CPUManager with the most basic accounting policy, i.e., one which simply aggregates announced consumptions of application threads, and with the highest possible granularity. This means that the triggerConsume() method is invoked only once in about 231 bytecode
9 This was experimentally determined as the maximal difference between the final results of any two complete benchmark suite executions.