1. INTRODUCTION
The Java programming language that evolved out of a research project started by Sun Microsystems in 1990 [Arnold and Gosling 1996; Gosling et al. 1996] is one of the most exciting technical developments in recent years. Java combines several features found in different programming paradigms into one language. Features such as platform independence for portability, an object-orientation model, support for multithreading, support for distributed programming, and automatic garbage collection, make Java very appealing to program developers. Java’s “write-once, run anywhere” philosophy captures much of what developers have been looking for in a programming language in terms of application portability, robustness, and security. The cost of Java’s flexibility, however, is its slow performance due to the high degree of hardware abstraction it offers.
To support portability, Java source code is translated into architecture neutral byte codes that can be executed on any platform that supports an implementation of the Java Virtual Machine (JVM). Most JVM implementations execute Java byte codes through either interpretation or Just-In-Time (JIT) compilation. Since both interpretation and JIT compilation require runtime translation of byte codes, they both result in relatively slow execution times for an application program. While advances with JIT compilers are making progress towards improving Java performance, existing Java execution techniques do not yet match the performance attained by conventional compiled languages. Of course, performance improves when Java is compiled directly to native machine code, but at the expense of diminished portability.
This survey describes the different execution techniques that are currently being used with the Java programming language. Section 2 describes the basic concepts behind the JVM. Section 3 discusses the different Java execution techniques, including interpreters, JIT and static compilers, and Java processors. In Section 4, we describe several optimization techniques for improving Java performance, including dynamic compilation, byte ode optimization, and parallel and distributed techniques. Section 5 reviews the existing benchmarks available to evaluate the performance of the various Java execution techniques with a summary of their performance presented in Section 6. Conclusions are presented in Section 7.