A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service
1. What is a Java Virtual Machine?
A Java virtual machine is an imaginary machine that is simulated by software on an actual computer. The Java Virtual Machine has its own hardware, such as the processor, stack, and register. It also has the corresponding command system.
Ii. Why is Java Virtual Machine Used?
A very important feature of Java is its independence from the platform. The use of Java virtual machines is the key to achieving this feature. General advanced languages must at least compile different target codes to run on different platforms. After the Java Virtual Machine is introduced, the Java language does not need to be re-compiled when running on different platforms. The Java Virtual Machine shields information related to specific platforms, so that the Java language compiler only needs to generate the target code (bytecode) that runs on the Java Virtual Machine ), it can be run on multiple platforms without modification. When executing the bytecode, the Java Virtual Machine interprets the bytecode as a machine instruction execution on a specific platform.
Iii. lifecycle of Java Virtual Machine
A running Java virtual machine has a clear task: to execute Java programs. It runs only when the program starts to run, and stops when the program ends. If you run three Java programs at the same time, there will be three running Java virtual machines.
The Java Virtual Machine always starts with a main () method. This method must be public, return void, and receive a string array directly. During program execution, you must specify the class name containing the main () method for the Java Virtual Machine.
The main () method is the starting point of the program. It is initialized as the initial thread of the program by the executed thread. Other threads in the program are started by him. There are two types of threads in Java: daemon and non-daemon ). The daemon thread is a thread used by the Java Virtual Machine. For example, the thread responsible for garbage collection is a daemon thread. Of course, you can also set your program as a daemon thread. The initial thread containing the main () method is not a daemon thread.
As long as there are common threads in the Java Virtual Machine for execution, the Java Virtual Machine will not stop. If you have sufficient permissions, you can call the exit () method to terminate the program.
Iii. Architecture of Java Virtual Machine
A series of subsystems, memory areas, data types, and user guides are defined in Java Virtual Machine specifications. These components constitute the internal structure of the Java Virtual Machine. They not only provide a clear internal structure for the implementation of the Java virtual machine, but also strictly regulate the external behavior implemented by the Java Virtual Machine.
Each Java Virtual Machine is composed of a Class Loader subsystem, which is responsible for loading types (Class class and Interface) in the program and giving a unique name. Each Java virtual machine has an execution engine that executes the commands contained in the loaded class.
The execution of a program requires a certain amount of memory space, such as bytecode, additional information of the loaded class, objects in the program, method parameters, return values, local variables, intermediate variables for processing, and so on. The Java virtual machine saves all the information in the data area. Although each implementation of a Java Virtual Machine includes a data zone, the provisions of the Java Virtual Machine specifications on the Data zone are very abstract. Many of the structural details are left to the Java Virtual Machine implementers themselves. Different Java Virtual Machine implementations have different memory structures. Some implementations may occupy a lot of memory, while others may only occupy a small amount of memory. Some implementations may use virtual memory, while others may not. This refined memory specification for Java virtual machines enables Java virtual machines to be implemented on a wide range of platforms.
One part of the data zone is the total of the entire program, and the other part is controlled by a separate thread. Each Java Virtual Machine includes the method area and heap, which are shared by the entire program. After the Java Virtual Machine loads and parses a class, it saves the parsed information from the class file and the method area. All objects created during program execution are saved in the heap.
When a thread is created, it will be allocated to its own PC register "PC register" (program counter) and java stack (java stack ). When a thread does not call a local method, the PC register stores the next instruction executed by the thread. The java stack stores the status of a thread when calling a method, including local variables, parameters for calling a method, return values, and intermediate variables for processing. When a local method is called, The status is stored in the native method stack, and may be in registers or other non-platform independent memory.
A java stack consists of stack frames (or frames. The stack block contains the status of the Java method call. When a thread calls a method, the Java Virtual Machine will press a new block into the java stack. When this method ends, the Java Virtual Machine will pop up and discard the corresponding block.
Java virtual machine uses java stack to store intermediate computing results instead of using registers. This means that the commands of the Java Virtual Machine are more compact and it is easier to implement the Java Virtual Machine on a device without registers.
4. Data Types)
The data used in all Java virtual machines has a specific data type, and the data types and operations are strictly defined in the Java Virtual Machine specifications. The data types in Java are divided into the original data type (primitive types) and reference data type (reference type ). The reference type depends on the actual object, but it is not the object itself. Raw data types do not depend on anything. They are the data they represent.
The original data types in all Java programming languages are the original data types of Java virtual machines, except Boolean ). When the compiler compiles Java source code into bytecode, it uses INTEGER (INT) or byte to indicate Boolean. In the Java Virtual Machine, an integer 0 is used to indicate the Boolean false, a non-zero integer is used to indicate the Boolean true, and a Boolean array is represented as a byte array, although they may be saved in a byte array or byte block (bit fields) in the heap.
Except the boolean type, all other primitive types are data types in Java virtual machines. In Java, data types are classified into: integer byte, short, Int, long; char and float and double. Data Types in Java have the same scope on any host.
There is also a primitive data type that cannot be used in the Java language in the Java Virtual Machine-return value type ). This type is used to implement "Finally classes" in Java programs. For details, see "Finally classes" in Chapter 18 ".
The reference type may be created as class type, interface type, and array type ). They all reference the dynamically created objects. When the reference type references null, it means that no object is referenced.
The Java virtual machine specification only defines the range of each data type, and does not define the space occupied by each type during storage. It is determined by the implementers of the Java Virtual Machine. For more information about floating point, see Chapter 14 "Floating Point
Typerange5. Byte Length
Byte8-bit signed two's complement INTEGER (-27 to 27-1, aggressive)
Short16-bit signed two's complement INTEGER (-215 to 215-1, aggressive)
Int32-bit signed two's complement INTEGER (-231 to 231-1, aggressive)
Long64-bit signed two's complement INTEGER (-263 to 263-1, aggressive)
Char16-bit unsigned UNICODE character (0 to 216-1, intrusive)
Float32-bit IEEE 754 Single-precision float
Double64-bit IEEE 754 double-precision float
Returnvalueaddress of an opcode within the same method
ReferenceReference to an object on the heap, or null
1) constant pool of type (the constant pool for the type)
All types in the constant pool are saved in an ordered set of constants, including constants of direct constants (literals) such as strings, integers, and floating point numbers, and symbolic references to types, fields, and methods. Each saved constant in the constant pool has an index, just like a field in the array. Because all types, fields, and methods are stored in the constant pool for character reference, it is also the main object of dynamic connection.
2) Field Information)
Field Names, field types, field modifiers (public, private, protected, static, final, volatile, transient, etc.), and the sequence of fields defined in the class.
3) method information)
Method Name, Return Value Type of the method (or void), number of method parameters, type and their sequence, field modifiers (public, private, protected, static, final, volatile, the sequence defined by methods in the class.
If it is not an abstract or local method, you need to save it.
The bytecode of the method, the size of the stack of the method's operands, and the size of the local variable area (for details later), and the exception list (for details, see chapter 17th "exceptions ".)
4) Class (static) variable (class variables)
Class variables are shared by all class instances, even if they are not accessible through class instances. These variables are bound to the class (instead of the class instance), so they are part of the Logical Data of the class. Before Java virtual machines use this class, they need to allocate memory for the class variable (non-final ).
Constants (final) are processed differently from non-final variables. Each type will copy a constant to its own constant pool. A constant is saved in the method area like a class variable, except that it is saved in the constant pool. (It is possible that class variables are shared by all instances, and the constant pool is unique to each instance ). Non-final class variables are saved as part of the data for the type that defines the declares them, the final constant is saved as part of the data for any type that uses them.
5) Reference to the Class Loader (a reference to class classloader)
For each type Loaded by a Java virtual machine, the virtual machine must save whether the type is loaded by the original class loader or class loader. The types loaded by the class loader must save a reference pointing to the class loader. This message is used when the class loader is dynamically connected. When a class references another class, the virtual machine must store the referenced type Loaded by the same class loader. This is also the process in which the Virtual Machine maintains different namespaces. For more information, see Chapter 8 "the linking model"
6) Reference to the class (a reference to class)
The Java virtual machine creates a java. Lang. class instance for each loaded type. You can also use the class method:
Public static class forname (string classname) to find or load a class and obtain the instance of the corresponding class. Through this class instance, we can access information in the Java Virtual Machine Method area. For more information, see javadoc of the class.
2. Method tables)
To effectively access all the data stored in the method area, the storage structure of the data must be carefully designed. In all the methods, apart from the original information above, there is also a data structure designed to speed up the storage, such as a list of methods. Each loaded non-abstract class will generate a list of methods for the Java Virtual Machine. The list contains references to all instance methods that this class may call, errors are reported for the methods called in the parent class.
When a Java program creates an instance or array of classes, it allocates memory for new objects in the heap. There is only one heap in the virtual machine, and all threads share it.
1. Garbage Collection)
Garbage collection is the main way to release objects that are not referenced. It may also move objects to reduce heap fragments. Garbage collection is not strictly defined in Java Virtual Machine specifications, but the implementation of a Java virtual machine must be managed in some way. For more information, see Chapter 9 "Garbage Collection ".
2. Object Representation)
The Java virtual machine specification does not define how objects are stored in the heap. Each object mainly stores the object variables defined in its class and its parent class. For the reference of a given object, the virtual machine must quickly locate the data of this object. In addition, you must provide a method to reference object data through an object, such as object reference in the method area, therefore, the data stored by an object usually contains a pointer pointing to the method area in some form.
A possible heap design is to divide the heap into two parts: the reference pool and the Object pool. An object reference is a local pointer to the reference pool. Each entry in the reference pool contains two parts: pointer to object data in the object pool and pointer to object-class data in the method area. This design makes it easy to organize the Java Virtual Machine heap fragments. When a virtual machine moves an object in the object pool, you only need to modify the pointer address of the corresponding reference pool. However, the data of each object to be accessed must be processed twice. Demonstrate the heap design. The heapoffish Applet in chapter 9 "Garbage Collection" demonstrates this design.
Another heap design is that an object reference is an offset pointer pointing to a pile of data and corresponding objects. This design facilitates object access, but the movement of objects is very complex. Demonstrate this design
When a program tries to convert an object to another type, the virtual machine needs to determine whether the conversion is the type of the object or its parent type. When the program applies the instanceof statement, it will do similar things. When a program calls an object's method, the virtual machine needs to dynamically bind it, and it must determine which type of method to call. This also requires the above judgment.
No matter which design is used by the Virtual Machine implementer, it can save a list of similar methods for each object. Because it can improve the speed of object method calling and is very important to improve the performance of virtual machines, but it is not required to implement similar data structures in the specifications of virtual machines. This structure is described. The figure shows all the data structures associated with an object reference, including:
1) a pointer to type data
2) list of methods of an object. The method list is an array of pointers to all methods that may be called. The method data includes three parts: the size of the opcode stack and the local variable area of the method stack; the method bytecode; and the exception list.
Each object in a Java virtual machine must be associated with a lock (mutex) used to synchronize multiple threads ). At the same time, only one object can own the Lock of this object. When a lock owns this object, he can apply for this lock multiple times, but he must also release the lock of the corresponding number of times to truly release this object lock. Many objects are not locked throughout the lifecycle. Therefore, this information must be added only when necessary. Many Java Virtual Machine implementations do not include "locked data" in the object data, but generate the corresponding data only when necessary. In addition to object locking, each object is logically associated with a "wait set" implementation. The locking group thread processes the shared data independently without interfering with other threads. "Wait
Set "helps the group threads collaborate to accomplish the same goal. "Wait set" is usually implemented through the wait () and Y () Methods of the object class.
Garbage collection also requires the related information of heap objects. The Java virtual machine specification indicates that a garbage collection method is used to run an object once, but the finalizer method is allowed to re-reference this object. When this object is not referenced again, you do not need to call the Finalize method again. Therefore, the virtual machine also needs to save information about whether the Finalize method has been run. For more information, see Chapter 9 "Garbage Collection"
3. array Representation)
In Java, an array is an object in the full sense. It is stored in the heap like an object and has a reference pointing to a class instance. All arrays of the same dimension and type have the same class. The length of the array is not considered. The corresponding class name is represented as dimension and type. For example, if the class of an integer data is "[I", the Class Name of the byte three-dimensional array is "[[[B", and the class name of the Two-dimensional object data is "[[ljava. lang. object ".
Multi-dimensional arrays are represented as arrays, such:
The array length, array data, and reference of some object array data must be saved in the heap. If an array is referenced, the virtual machine should be able to obtain the length of an array, access specific data through the index, and call the object-defined method. Object is the direct parent class of all data classes. For more information, see Chapter 6 "class files ".
9. The program counter)
A program counter is created when each thread starts execution. The program counter has only one word, so it can save a local pointer and returnvalue. During thread execution, the program counter stores the address of the instruction being executed. This address can be used as a local pointer or an offset pointer starting from the method bytecode. If you execute a local method, the program counter value is not defined.
10. java stack)
When a thread starts, the Java Virtual Machine creates a java stack for it. Java stacks use discrete frame classes to record the state of threads. There are only two types of java stack operations for Java Virtual Machine heap: press-in and pop-up frames.
The method being executed in the thread is called the current method, and the frame corresponding to the current method is called the current frame ). The class defining the current method is called the current class, and the constant pool of the current class is called the current constant pool .). When the thread is executed, the Java Virtual Machine tracks the current class and the current constant pool. But when a thread operates the data stored in the frame, it only operates the data of the current frame.
When a thread calls a method, a new frame is generated and pushed into the java stack of the thread. The new frame is changed to the current frame. When the method is executed, it uses the parameters of the current frame storage method, local variation, intermediate structure, and other data. There are two exit Methods: normal exit and exceptional release. Regardless of the method, the Java Virtual Machine will pop up and discard the method frame, and the frame of the previous method will change to the current frame.
All the data stored in the frame can only be accessed by the thread that owns it, And the thread cannot access the data in the stack of other threads. Therefore, multithreading synchronization is not required when accessing local variables of a method.
Like the method area and heap, the java stack does not need continuous memory space, which can be stored in a scattered memory space or stack. The specific data and length of the stack are defined by the implementers of the Java Virtual Machine. Some implementations may provide methods to execute the maximum and minimum values of stacks.
11. stack frame)
Stack frames include local variables, operand stacks, and frame data. The size of the local variables and the operand stack is in the unit of word. They are determined after compilation. The size of the frame data depends on the implementation. When a program calls a method, the virtual machine obtains the size of the local variable and operand Stack from the class data, creates an appropriate size and frame, and then pushes it into the java stack.
1. Local Variables)
Local variables are organized into an array with 0 counts in the java stack frame, and the command gets the corresponding value from the local variable area by providing their indexes. Int, float, reference, returnvalue occupies one word. byte, short, and Char are converted to int and stored. Long and Doubel occupy two words.
The command returns the value of long and Doubel by providing the first one of the two word indexes. For example, if a long value is stored on index 3 and 4, the command can use 3 to obtain the long value.
The local variable area contains the method parameters and local variables. The compiler places the parameters of the method in the order they declare before the array. However, the compiler can arrange local variables in the local variable array at will, and even two local variables can share an address. For example, when two local variables are in two non-overlapping areas, just like loop variable I, j.
Virtual Machine implementers can use any structure to describe the data in the local variable area. The virtual machine specification does not define how to store long and Doubel.
2. operand Stack)
Like local variables, the operand stack is also organized into an array in the unit of words. However, unlike local variables, index access is implemented through push and pop values. If a command pushes a value to the stack, the next command can pop and use this value.
Unlike program counters, the operand stack cannot be directly accessed by commands. commands can directly access the operand stack. A Java virtual machine is a stack-based, rather than a register-based, because its commands get the operands from the stack rather than in the same register. Of course, commands can also be operands from other places, such as the operation code behind the command, or the constant pool. However, Java VM commands mainly obtain the required operands from the operand stack.
The Java Virtual Machine regards the operand stack as the work zone. Many instructions first push the result back to the operand stack by taking the pop value from the operand stack. The execution process of an add command is shown in. Execute the iload_0 and iload_1 commands to extract the two numbers to be added from the local method area and push them to the operand stack; then execute the iadd command, pop out two values, and add the result pusp into the operand stack. Finally, execute the istore_2 command, pop out the result, and assign the value to the local method area.
3. frame data)
In addition to processing local variables and operand stacks, java stack frames also include the data required to support constant pools, method return values, and exception distribution. They are stored in frame data.
When a VM uses a command that points to a constant pool reference, it accesses the required information through the pointer pointing to the constant zone in the frame data. As mentioned above, references in the constant area are symbolic references at the beginning. Even when the virtual machine checks these references, they are also character references. Therefore, the VM needs to convert this reference at this time.
When a method returns normally, the VM needs to recreate the stack frame of the method that calls this method. If the returned value is returned for the executed method, the virtual machine needs to push the value to the stack of the operand of the calling method.
Frame data also contains references to abnormal tables used by virtual machines to handle exceptions. The exception table defines a byte code protected by a catch statement. Each individual in the exception table contains the range of bytecode to be protected, and the location of the bytecode to be executed when the exception is captured. When a method throws an exception, the Java virtual machine uses the exception table to determine how to handle the exception. If the VM finds a catch match, it will give the control to the catch statement. If no matching catch is found, the method returns an exception and continues the process in the called method.
In addition to the preceding three functions, frame data may also contain implementation-dependent data, such as debugging information.
12. Local method Stack
The local method area depends on different implementations of virtual machines. Virtual Machine implementers can decide which mechanism to use to execute local methods.
Any native method interface uses some form of local method stack.
13. execution engine
The core of a Java virtual machine is the execution engine. In Java Virtual Machine specifications, the execution engine is described as a series of commands. For each instruction, the specification describes what they should do, but does not say how to do it.
1. Instruction Set
In a Java virtual machine, the byte code stream of a method is a sequence of commands. Each instruction consists of a byte opcode and possible operands (operands ). The operation code indicates what to do. The operations provide additional information that may be required to execute the operation code. An abstract execution engine executes a command each time. This process occurs in every execution thread.
Sometimes, the execution engine may encounter a command that calls a local method. In this case, the execution engine tries to call a local method, but when the local method returns, the execution engine continues to execute the next instruction in the byte code stream. The local method can also be seen as an extension of the instruction set in the Java Virtual Machine.
Deciding to execute the next command is also part of the execution engine. The execution engine has three methods to obtain the next instruction. Most commands will execute the commands that meet with him; some commands like Goto and return will decide their next command when they execute; when an instruction throws an exception, the execution engine matches the catch statement to determine the next instruction to be executed.
Platform independence, network mobility, and security affect the Java Virtual Machine instruction set design. Platform independence is one of the main factors influencing instruction set design. The stack-based structure enables Java virtual machines to be implemented on more platforms. Smaller operation codes and a compact structure allow byte codes to take advantage of network bandwidth more effectively. One-time bytecode verification makes the bytecode safer without affecting too much performance.
2. Execution Technology
Many execution technologies can be used in Java Virtual Machine implementation: interpretation execution, timely compilation (just-in-time compiling), hot-spot compiling, native execution in silicon.
Java virtual machine specification defines a thread model to be implemented on more platforms. Local threads can be used when a Java thread model is a target. By using local threads, the threads in the Java program can be truly executed simultaneously on a multi-processor machine.
One price of the Java thread model is the thread priority. A Java thread can run on a priority of 1 to 10. 1 is the lowest and 10 is the highest. If the designer uses a local thread, they may map the 10 priorities to the local priority. The Java virtual machine specification only defines that a thread with a higher priority can have some CPU time, while a thread with a lower priority can also obtain some CPU time when all high-priority threads are congested, but this is not guaranteed: low-priority threads cannot obtain a certain CPU time when there is no congestion in high-priority threads. Therefore, if you need to collaborate between different threads, you must use synchronizatoin )".
Synchronization involves two parts: Object locking and thread wait and activation ). The help thread of the object lock can be independent from other threads. Thread waiting and activation allow different threads to collaborate.
In Java Virtual Machine specifications, Java threads are described as variables, primary memory, and working memory. Each Java Virtual Machine instance has a primary memory, which contains all program variables: object and number combination variables. Each thread has its own working memory, which stores copies of variables that may be used by the thread. Rules:
1) copy the variable value from the primary memory to the working memory.
2) write the value in the working memory to the main memory.
If a variable is not synchronized, the thread may update the variable in the main memory in any order. To ensure correct execution of multi-threaded programs, the synchronization mechanism must be used.
14. native method Interface)
The implementation of Java virtual machine does not require local method interfaces. Some implementations may not support local method interfaces at all. Sun's local method interface is JNI (Java Native Interface ).
15. Real Machine)
16. Mathematical Methods: Simulation (eternal Math: A simulation)
Note: Java virtual machine working principle from http://java.chinaitlab.com/Jvm/534088_1---2.html
Start building with 50+ products and up to 12 months usage for Elastic Compute Service