Java: Fat and Slow?

Java: Fat and Slow?

67957_Wiley_Giguere_CH02x 10/17/2000 4:50 PM Page 17 CHAPTER 2 Java: Fat and Slow? sk Java zealots if Java is slow, and watch them bristle with annoyance. “Of course not,” they will say. “Performance is perfectly adequate with A just-in-time compilers and is even better with the new HotSpot tech- nology.” Ask them if Java is fat, and you will receive a similar response: “The Java runtime is a bit large, but that’s only because it provides so many useful APIs. You’d get that kind of size with any sys- tem.” And you know, they are not wrong, either. On server and desk- top platforms, Java does work. In particular, Java has made huge inroads as a server-side programming language, due primarily to the advantages that we discussed in the introduction. As for performance issues, remember that in a server environment, installing more or faster CPUs or more memory or even spreading the load across sev- eral machines can often tackle these issues. 17 67957_Wiley_Giguere_CH02x 10/17/2000 4:50 PM Page 18 18 CHAPTER 2 Still, there is a perception among developers that Java is fat and slow, but its convenience outweighs its performance issues. This perception is a concern to us, however, because we are interested in writing Java programs that run on small computing devices. Unlike server or even desktop platforms, we cannot just throw more hardware at small- device performance problems. In this chapter, we look at why Java is fat and slow and how those char- acteristics affect our desire to run Java programs on small devices. First, we examine the architecture of Java. Then, we follow its evolu- tion from a language for writing platform-independent client applica- tions and finally to its current role as a language for server and enterprise programming. The Architecture of Java We start by looking at how Java works. The basic architecture has not changed since Java was first released, although there has been consid- erable effort to improve parts of it. If you are already familiar with the architecture, feel free to skip to the next section—although you might find a refresher course useful. Overview The code that runs a Java program is referred to generally as a Java runtime environment (JRE). A JRE is a combination of native (com- piled for a specific machine architecture) and Java code that is targeted for a particular operating system. JREs are embedded in other applica- tions, such as Web browsers, or are available directly from a shell prompt or desktop user interface. A JRE is generally packaged as a set of shared libraries (the native code) and archives (the Java code). There are alternative packagings, however. Parts of a JRE can be incorporated directly into hardware, creating the so-called Java chips. Or, alternatively, Java programs—or parts of programs—can be compiled directly into native code, eliminat- ing sections of a conventional JRE. In all cases, however, the semantics of Java code execution must be preserved, so we will discuss things from the viewpoint of a conventional JRE. 67957_Wiley_Giguere_CH02x 10/17/2000 4:50 PM Page 19 Java: Fat and Slow? 19 Sun’s Runtime Environment As we discuss the architecture of Java, we will use the term JRE in a generic sense. More specifically, however, JRE refers to Sun’s runtime environment, which is a downloadable, self-contained package that is meant for distribution with Java applications to be installed on machines that do not already have the capa- bility to run Java programs. We will discuss that JRE later in this chapter. Packaging issues aside, a JRE consists of two major components: an execution engine and a pair of runtime libraries. The Execution Engine The execution engine is the core of the JRE and is responsible for load- ing and running Java programs. The requirements for the execution engine are contained in The Java Virtual Machine Specification (JVMS), the official reference with which all implementations must conform in order to qualify as a JRE. The execution engine itself is split into several components: a virtual machine, a garbage collector, a class verifier, a class loader, and a native code interface. Compilation versus Execution There are two important documents that tool implementers—the programmers who write compilers, debuggers, runtime environments, and other applications that other programmers use—refer to when dealing with Java. The first is the JVMS. The second is The Java Language Specification (JLS). The JLS describes the syntax and semantics of the Java programming language, while the JVMS describes how to run Java programs. In general terms, the JLS is about compiling Java, while the JVMS is about executing Java. We will see that you can also use the JVMS to run programs that are written in other languages. The Java virtual machine (often referred to as the VM or JVM) is the most visible part of the execution engine. In fact, the two are usually considered synonymous. For our discussions in this section, we will treat them as separate entities, but in the remainder of this chapter 67957_Wiley_Giguere_CH02x 10/17/2000 4:50 PM Page 20 20 CHAPTER 2 (starting with our look at the evolution of Java) and in the chapters that follow, we will use the terms VM and JVM to refer to the complete exe- cution engine. The various pieces that we discuss here are so closely tied together that for all intents and purposes, we can treat them as a single entity. The Virtual Machine The heart of the execution engine is the virtual machine. In computer science, a virtual machine is an abstract, idealized computer with its own instruction set. Virtual machines are implemented in software and are used for teaching and portability purposes—in any situation where it is useful to hide the messy details of an actual, physical architecture. Programs that are coded for a virtual machine can be run on any archi- tecture simply by porting the virtual machine—which is, after all, just another application—to the new architecture. This system is the basis of Java’s portability, along with the classfile format and the core run- time libraries. Portability Is More Than a VM Using a VM does not guarantee complete portability, however. True portability (usually referred to as binary portability) is achieved when the file format used to store the program is itself portable and the runtime libraries that the program depends on are present on each target architecture. Java’s write once, run any- where portability is based on those three components: the VM, the classfile for- mat, and the standard runtime libraries. Bytecodes The instruction set for the JVM is described in the JVMS. The instruc- tions are commonly referred to as bytecodes, because many of them are a single byte in length. There are Java bytecodes for common oper- ations such as reading or writing memory, adding or subtracting num- bers, and branching—operations that any machine architecture supports. There are also bytecodes for implementing certain features that are specific to the Java language itself, such as the instanceof keyword. The JVM is built around the Java type model, so it under- stands the scalar types and object references that the language uses. 67957_Wiley_Giguere_CH02x 10/17/2000 4:50 PM Page 21 Java: Fat and Slow? 21 You can use a JVM to run programs that are written in other languages, but only if those languages can be compiled into Java bytecodes (the tight linkage between the VM and the Java language can make that diffi- cult). For an example of a non-Java language that can run on a JVM, refer to IBM’s NetREXX, which is available from http://www2.hursley. ibm.com/netrexx. A JVM is a stack-based machine that uses no registers, except for a pro- gram counter to track the instruction that is currently executing. Most bytecodes manipulate the stack in some way, using it as a place to retrieve input and to store results. For example, consider the following Java code: int a = 5; int b = 3; int c; c = a + b; One possible translation into bytecode would be as follows: bipush 5 // push single-byte value 5 on stack as int istore 0 // pop int value and store in first local variable bipush 3 // push single-byte value 3 on stack as int istore 1 // pop int value and store in second local variable iload 0 // load int from first local variable and push on stack iload 1 // do the same for second local variable iadd // pop top two ints from stack, add, and push result istore 2 // pop int value and store in third local variable Using a stack makes it easy to implement the virtual machine on any architecture, because there is no dependence on specialized registers. It does increase the size of the compiled code, however, because of the necessity to push and pop values onto and from the stack. Consider this hypothetical example obtained by adding two registers, A and B, to the virtual machine: // hypothetical only! load_A 5 // load value 5 into register A store_A 0 // store register A into first local variable load_B 3 // load value 3 into register B store_B 1 // store register B into second local variable add_A_B // add A and B, storing result back in A store_A 2 // store register A into third local variable 67957_Wiley_Giguere_CH02x 10/17/2000 4:50 PM Page 22 22 CHAPTER 2 This imaginary example is 11 bytes long (each bytecode takes a single byte, and each of the operands takes another byte), while the previous example is 15 bytes long.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    34 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us