Você está na página 1de 6

JAVA VIRTUAL MACHINE

What is the Java Virtual Machine? Why is it here?

The Java Virtual Machine, or JVM, is an abstract computer that runs compiled Java programs. The JVM is 
"virtual" because it is generally implemented in software on top of a "real" hardware platform and operating system. All 
Java programs are compiled for the JVM. Therefore, the JVM must be implemented on a particular platform before 
compiled Java programs will run on that platform. 

The JVM plays a central role in making Java portable. It provides a layer of abstraction between the compiled Java 
program and the underlying hardware platform and operating system. The JVM is central to Java's portability because 
compiled Java programs run on the JVM, independent of whatever may be underneath a particular JVM implementation. 

What makes the JVM lean and mean? The JVM is lean because it is small when implemented in software. It was 
designed to be small so that it can fit in as many places as possible ­­ places like TV sets, cell phones, and personal 
computers. The JVM is mean because it of its ambition. "Ubiquity!" is its battle cry. It wants to be everywhere, and its 
success is indicated by the extent to which programs written in Java will run everywhere. 

Java bytecodes

Java programs are compiled into a form called Java bytecodes. The JVM executes Java bytecodes, so Java 
bytecodes can be thought of as the machine language of the JVM. The Java compiler reads Java language source (.java) 
files, translates the source into Java bytecodes, and places the bytecodes into class (.class) files. The compiler generates one 
class file per class in the source. 

To the JVM, a stream of bytecodes is a sequence of instructions. Each instruction consists of a one­byte opcode and 
zero or more operands. The opcode tells the JVM what action to take. If the JVM requires more information to perform the 
action than just the opcode, the required information immediately follows the opcode as operands. 

A mnemonic is defined for each bytecode instruction. The mnemonics can be thought of as an assembly language 
JAVA VIRTUAL MACHINE

for the JVM. For example, there is an instruction that will cause the JVM to push a zero onto the stack. The mnemonic for 
this instruction is iconst_0, and its bytecode value is 60 hex. This instruction takes no operands. Another instruction causes 
program execution to unconditionally jump forward or backward in memory. This instruction requires one operand, a 16­bit 
signed offset from the current memory location. By adding the offset to the current memory location, the JVM can 
determine the memory location to jump to. The mnemonic for this instruction is goto, and its bytecode value is a7 hex.

Virtual parts

The "virtual hardware" of the Java Virtual Machine can be divided into four basic parts: the registers, the stack, the 
garbage­collected heap, and the method area. These parts are abstract, just like the machine they compose, but they must 
exist in some form in every JVM implementation. 

The size of an address in the JVM is 32 bits.The JVM can, therefore, address up to 4 gigabytes (2 to the power of 
32) of memory, with each memory location containing one byte. Each register in the JVM stores one 32­bit address. The 
stack, the garbage­collected heap, and the method area reside somewhere within the 4 gigabytes of addressable memory. 
The exact location of these memory areas is a decision of the implementor of each particular JVM. 

A word in the Java Virtual Machine is 32 bits. The JVM has a small number of primitive data types: byte (8 bits), 
short (16 bits), int (32 bits), long (64 bits), float (32 bits), double (64 bits), and char (16 bits). With the exception of char, 
which is an unsigned Unicode character, all the numeric types are signed. These types conveniently map to the types 
available to the Java programmer. One other primitive type is the object handle, which is a 32­bit address that refers to an 
object on the heap. 

The method area, because it contains bytecodes, is aligned on byte boundaries. The stack and garbage­collected 
heap are aligned on word (32­bit) boundaries. 

The proud, the few, the registers

The JVM has a program counter and three registers that manage the stack. It has few registers because the bytecode 
instructions of the JVM operate primarily on the stack. This stack­oriented design helps keep the JVM's instruction set and 
implementation small. 

The JVM uses the program counter, or pc register, to keep track of where in memory it should be executing 
instructions. The other three registers ­­ optop register, frame register, and vars register ­­ point to various parts of the stack 
frame of the currently executing method. The stack frame of an executing method holds the state (local variables, 
intermediate results of calculations, etc.) for a particular invocation of the method. 

The method area and the program counter
JAVA VIRTUAL MACHINE

The method area is where the bytecodes reside. The program counter always points to (contains the address of) 
some byte in the method area. The program counter is used to keep track of the thread of execution. After a bytecode 
instruction has been executed, the program counter will contain the address of the next instruction to execute. After 
execution of an instruction, the JVM sets the program counter to the address of the instruction that immediately follows the 
previous one, unless the previous one specifically demanded a jump. 

The Java stack and related registers

The Java stack is used to store parameters for and results of bytecode instructions, to pass parameters to and return values 
from methods, and to keep the state of each method invocation. The state of a method invocation is called its stack frame. 
The vars, frame, and optop registers point to different parts of the current stack frame.

There are three sections in a Java stack frame: the local variables, the execution environment, and the operand stack. The 
local variables section contains all the local variables being used by the current method invocation. It is pointed to by the 
vars register. The execution environment section is used to maintain the operations of the stack itself. It is pointed to by the 
frame register. The operand stack is used as a work space by bytecode instructions. It is here that the parameters for 
bytecode instructions are placed, and results of bytecode instructions are found. The top of the operand stack is pointed to by 
the optop register.

The execution environment is usually sandwiched between the local variables and the operand stack. The operand stack of 
the currently executing method is always the topmost stack section, and the optop register therefore always points to the top 
of the entire Java stack. 

The garbage­collected heap

The heap is where the objects of a Java program live. Any time you allocate memory with the new operator, that memory 
comes from the heap. The Java language doesn't allow you to free allocated memory directly. Instead, the runtime 
environment keeps track of the references to each object on the heap, and automatically frees the memory occupied by 
objects that are no longer referenced ­­ a process called garbage collection. 

Eternal math: a JVM simulation

The applet below simulates a JVM executing a few bytecode instructions. The instructions in the simulation were 
generated by the javac compiler given the following java code: 

class Act {
public static void doMathForever() {
int i = 0;
while (true) {
i += 1;
JAVA VIRTUAL MACHINE

i *= 2;
}
}
}
The instructions in the simulation represent the body of the doMathForever() method. These instructions were 
chosen because they are a short sequence of bytecodes that do something mildly interesting on the stack. This simulation 
stars the registers, the stack, and the method area. The heap is not involved in this bytecode sequence, so it is not shown as 
part of the applet's user interface. All numbers in the simulation are shown in hex. 

As our story opens, the program counter (pc register) is pointing to an iconst_0 instruction. The iconst_0 
instruction is in the method area, where bytecodes like to hang out. 

When you press the Step button, the JVM will execute the single instruction that is being pointed to by the program 
counter. So, the first time you press the Step button, the iconst_0 instruction, which pushes a zero onto the stack, will be 
executed. After this instruction has executed,the program counter will be pointing to the next instruction to 
execute.Subsequent presses of the Step button will execute subsequent instructions and the program counter will lead the 
way. Pressing the Reset button will cause the simulation to start over at the beginning. 

The value of each register is shown two ways. The contents of each register, a 32­bit address, is shown in hex across 
the top of the simulation. Additionally, I put a small pointer to the address contained in each register next to the address in 
either the stack or the method area. The address contained by the program counter, for example, has a pc> next to it in the 
method area.

ADVANTAGES OF JVM
A self­contained operating environment that behaves as if it is a separate computer. For example, Java 
applets run in a Java virtual machine (VM) that has no access to the host operating system. This design has two 
advantages: 
• System Independence: A Java application will run the same in any Java VM, regardless of the hardware and 
software underlying the system. 
• Security: Because the VM has no contact with the operating system, there is little possibility of a Java program 
damaging other files or applications. 

The second advantage, however, has a downside. Because programs running in a VM are separate from the operating
system, they cannot take advantage of special operating system features. 

WHY GARBAGE COLLECTION

The Java virtual machine's heap stores all objects created by a running Java application. Objects are created by the 
new, newarray, anewarray, and multianewarray instructions, but never freed explicitly by the code. 
Garbage collection is the process of automatically freeing objects that are no longer referenced by the program. 
JAVA VIRTUAL MACHINE

This chapter does not describe an official Java garbage­collected heap, because none exists. As mentioned in earlier 
chapters, the Java virtual machine specification does not require any particular garbage collection technique. It doesn't even 
require garbage collection at all. But until infinite memory is invented, most Java virtual machine implementations will 
likely come with garbage­collected heaps. This chapter describes various garbage collection techniques and explains how 
garbage collection works in Java virtual machines. 

Accompanying this chapter on the CD­ROM is an applet that interactively illustrates the material presented in the 
chapter. The applet, named Heap of Fish, simulates a garbage­collected heap in a Java virtual machine. The simulation­­
which demonstrates a compacting, mark­and­sweep collector­­allows you to interact with the heap as if you were a Java 
program: you can allocate objects and assign references to variables. The simulation also allows you to interact with the 
heap as if you were the Java virtual machine: you can drive the processes of garbage collection and heap compaction. At the 
end of this chapter, you will find a description of this applet and instructions on how to use it. 

Why Garbage Collection?
The name "garbage collection" implies that objects no longer needed by the program are "garbage" and can be 
thrown away. A more accurate and up­to­date metaphor might be "memory recycling." When an object is no longer 
referenced by the program, the heap space it occupies can be recycled so that the space is made available for subsequent new 
objects. The garbage collector must somehow determine which objects are no longer referenced by the program and make 
available the heap space occupied by such unreferenced objects. In the process of freeing unreferenced objects, the garbage 
collector must run any finalizers of objects being freed. 

In addition to freeing unreferenced objects, a garbage collector may also combat heap fragmentation. Heap 
fragmentation occurs through the course of normal program execution. New objects are allocated, and unreferenced objects 
are freed such that free portions of heap memory are left in between portions occupied by live objects. Requests to allocate 
new objects may have to be filled by extending the size of the heap even though there is enough total unused space in the 
existing heap. This will happen if there is not enough contiguous free heap space available into which the new object will fit. 
On a virtual memory system, the extra paging (or swapping) required to service an ever growing heap can degrade the 
performance of the executing program. On an embedded system with low memory, fragmentation could cause the virtual 
machine to "run out of memory" unnecessarily. 

Garbage collection relieves you from the burden of freeing allocated memory. Knowing when to explicitly free 
allocated memory can be very tricky. Giving this job to the Java virtual machine has several advantages. First, it can make 
you more productive. When programming in non­garbage­collected languages you can spend many late hours (or days or 
weeks) chasing down an elusive memory problem. When programming in Java you can use that time more advantageously 
by getting ahead of schedule or simply going home to have a life. 

A second advantage of garbage collection is that it helps ensure program integrity. Garbage collection is an 
JAVA VIRTUAL MACHINE

important part of Java's security strategy. Java programmers are unable to accidentally (or purposely) crash the Java virtual 
machine by incorrectly freeing memory. 

A potential disadvantage of a garbage­collected heap is that it adds an overhead that can affect program 
performance. The Java virtual machine has to keep track of which objects are being referenced by the executing program, 
and finalize and free unreferenced objects on the fly. This activity will likely require more CPU time than would have been 
required if the program explicitly freed unnecessary memory. In addition, programmers in a garbage­collected environment 
have less control over the scheduling of CPU time devoted to freeing objects that are no longer needed. 

Você também pode gostar