The cross-platform nature of Java because it has virtual machines for different platforms.
1.2 Java Virtual machine
The main task of the Java Virtual machine is to load the class file and execute the bytecode. As you can see from the figure below, the Java virtual machine contains a class loader (class loader) that can load class files from programs and APIs, and only classes that are required for program execution in the Java API are loaded, and bytecode is executed by the execution engine.
When a Java virtual machine is implemented by software on the host operating system, the Java program interacts by invoking the local method and host. Java methods are written in the Java language, compiled into bytecode, and stored in a class file. The local method is written by c/c++/assembly language, compiled into processor-related machine code, stored in a dynamic-link library, and the format is proprietary to each platform. So the local method is the connection between the Java program and the underlying host operating system.
Because the Java virtual machine does not know how a class file is created or tampered with, it implements a class file detector to ensure that the types defined in the class file are safe to use. The class File Checker uses four separate scans to ensure the robustness of the program:
Structure checking of class files
Semantic checking of type data
BYTE code Verification
Symbolic Reference validation
Java Virtual machines also perform other built-in security operations while executing bytecode, guaranteeing the robustness of Java programs as a Java programming language, as well as the characteristics of Java virtual machines:
Type-safe Reference conversions
Structured Memory Access
Automatic garbage collection
Array bounds checking
null reference check
Java Virtual machines perform calculations with certain data types. Data types can be divided into two categories: the base type and the reference type, as shown in the following figure:
But a Boolean is a bit special, and when the compiler compiles Java source code into bytecode, it uses an int or a byte to represent a Boolean. In the Java virtual machine, false is represented by 0, and true is represented by all nonzero integers. As with the Java language, the basic type of a Java virtual machine is consistent anywhere, regardless of the host platform, a long signed integer with a 64-bit binary complement in any virtual machine.
For ReturnAddress, this basic type is used to implement the finally clause in the Java program, which the Java programmer cannot use, and its value points to the opcode of a virtual machine instruction.
2 architecture
In the Java Virtual Machine specification, the behavior of a virtual machine instance is described separately by subsystem, memory area, data type, and instruction, which together demonstrate the internal architecture of an abstract virtual machine.
2.1 Class file
The Java class file contains all the information about a class or interface. The "basic type" of the class file is as follows:
What the class file contains:
2.2 Class Loader Subsystem
The class loader subsystem is responsible for locating and loading type information. In fact, the Java virtual machine has two kinds of loaders: System loader and user custom loader. The former is part of the Java Virtual Machine implementation, and the latter is part of the Java program.
Launch class loader (bootstrap class loader): It is used to load Java core libraries, which are implemented in native code and do not inherit from Java.lang.ClassLoader.
Extended class loader (Extensions class loader): It is used to load Java extension libraries. The implementation of the Java virtual machine provides an extension library directory. The class loader finds and loads Java classes in this directory.
Application class loader (Application class loader): It loads Java classes based on the Java application's Classpath (CLASSPATH). In general, Java-applied classes are loaded by it. It can be obtained by Classloader.getsystemclassloader ().
In addition to the class loaders provided by the system, developers can implement their own class loaders by inheriting the Java.lang.ClassLoader class to meet some special requirements.
The class loader subsystem involves several other components of the Java Virtual machine and classes from the Java.lang library. The method defined by ClassLoader provides an interface for the program to access the class loader mechanism. In addition, for each loaded type, the Java virtual machine creates an instance of the Java.lang.Class class for it to represent the type. As with other objects, user-defined class loaders and instances of class classes are placed in an in-memory heap area, while the type information is mounted in the method area.
In addition to locating and importing binary class files, the class loader subsystem must also be responsible for verifying the correctness of the imported classes, assigning and initializing memory for class variables, and parsing symbolic references. These actions also need to be performed in the following order:
Mount (Find and load binary data of type)
Connections (performing validation: ensuring the correctness of the type being imported; preparation: allocating memory for class variables and initializing them to default values; parsing: Converting a symbolic reference in a type to a direct reference)
Initialization (class variable initialized to correct initial value)
In the Java virtual machine, the information about the type being loaded is stored in the memory of a method area. When a virtual machine loads a type, it uses the class loader to locate the corresponding class file, then reads the class file and transmits it to the virtual machine, and then the virtual machine extracts the type information and stores the information in the method area. The method area can also be collected by the garbage collector, because the virtual machine allows the Java program to be dynamically extended through the user-defined class loader.
The following information is stored in the method area:
Fully qualified name of this type (such as fully qualified name Java.lang.Object)
The fully qualified name of the direct superclass of this type
Whether this type is a class type or an interface type
This type of access modifier (public, abstract, final subset)
Ordered list of fully qualified names of any direct hyper-interfaces
The type of Chang (an ordered set, including direct constants [string, Integer, and floating point constants] and symbolic references to other types, fields, and methods)
Field information (field name, type, modifier)
Method information (method name, return type, number of parameters and type, modifier)
All class (static) variables except constants
Refers to a reference to the ClassLoader class (when each type is loaded, the virtual machine must track whether it is loaded by the boot class loader or by the user-defined class loader)
Reference to the class class (for each loaded type, the virtual machine creates an instance of the Java.lang.Class class for it accordingly.) For example, if you have a reference to an object to the Java.lang.Integer class, you can get a class object that represents the Java.lang.Integer class simply by calling the GetClass () method referenced by the integer object.
All class instances or arrays that the Java program creates at run time (the array is a real object in the Java Virtual Machine) are placed in the same heap. Because the Java Virtual machine instance has only one heap of space, all threads will share this heap. Note that the Java Virtual machine has an instruction to allocate objects in the heap, but there is no instruction to release the memory, because the virtual machine gives the task to the garbage collector to process it. The Java Virtual Machine specification does not enforce the garbage collector, it only requires that the virtual machine implementation must "somehow" manage its own heap space. For example, an implementation may have only a fixed size of the heap space, when the space is filled, it simply throws OutOfMemory exception, does not consider the problem of garbage collection, but it is in line with the specification.
The Java Virtual Machine specification does not dictate how Java objects are represented in the heap, which determines how the virtual machine's implementation is designed. A possible heap design is as follows:
A handle pool, an object pool. A reference to an object is a local pointer to a handle pool. The benefits of this design benefit the defragmentation of the heap, and when moving objects in the object pool, the handle part simply changes the pointer to the new address of the object. The disadvantage is that each access to an object's instance variable passes through two pointers.
2.5 Java Stack
Whenever a thread is started, the Java Virtual Opportunity assigns it a Java stack. The Java stack consists of a number of stack frames, one stack frame containing the state of a Java method invocation. When a thread invokes a Java method, the virtual machine presses a new stack frame into the Java stack of the thread, and when the method returns, the stack frame pops up from the Java stack. The state of Java method calls in Java stack storage threads-including local variables, parameters, return values, and intermediate results of operations. The Java Virtual machine has no registers, and its instruction set uses a Java stack to store intermediate data. The reason for this design is to keep the Java Virtual machine's instruction set as compact as possible, and to make it easier for Java virtual machines to be implemented on platforms with few general-purpose registers. In addition, the stack based architecture also facilitates code optimization for dynamic compilers and Just-in-time compilers implemented by some virtual machines at run time.
2.5.1 Stack Frame
The stack frame is composed of local variable area, operand stack and frame data area. When a virtual machine invokes a Java method, it obtains the size of the local variable area and operand stack of this method from the type information of the corresponding class, and allocates the stack frame memory according to this, and then presses into the Java stack.
2.5.1.1 local Variable Area
The local variable area is organized into an array that is counted in word length, starting at 0. BYTE-code directives use the data in the index starting at 0. values of type int, float, reference, and ReturnAddress occupy an item in the array, while the values of type Byte, short, and char are converted to int values and also occupy one item before they are stored in the array. However, the values of type long and double occupy two consecutive items in the array.
2.5.1.2 Stack of operands
As with the local variable area, the operand stack is also organized into an array in word length. It is accessed through standard stack operations – press stacks and stacks. Because the program counter cannot be accessed directly by program instructions, the Java Virtual machine's instruction is to get the operand from the operand stack, so it runs on a stack rather than on a register. The virtual machine takes the operand stack as its workspace because most of the instructions eject the data from here, perform the operation, and then press the result back to the operand stack.
2.5.1.3 Frame Data area
In addition to local variables and operand stacks, the Java stack frame also requires a frame data area to support constant pool parsing, normal method return, and exception distribution mechanisms. Whenever a virtual confidential executes an instruction that needs to use constant pool data, it accesses it through a pointer to a constant pool in the frame data area. In addition to the parsing of a constant pool, the frame data area also helps the virtual machine handle the normal end of Java methods or abort the exception. If you end normally by return, the virtual machine must restore the stack frame of the method that originated the call, including setting the program counter to the next instruction to initiate the calling method; If the method has a return value, the virtual machine needs to push it into the operand stack of the method that originated the call. To handle an exception exit during Java method execution, the frame data area also holds a reference to this method exception table.
2.6 Program Counter
For a running Java program, each thread has its program counter. Program counters are also called PC registers. The program counter can hold both a local pointer and a returnaddress. When a thread executes a Java method, the value of the program counter is always the address of the next executed instruction. The address here can be a local pointer, or it can be an offset from the method's starting instruction in the byte code. If the thread is executing a local method, then the value of the program counter is "undefined".
2.7 Local Method Stacks
Any local method interface will use a local method stack. When a thread invokes a Java method, the virtual opportunity creates a new stack frame and presses it into the Java stack. When it calls the local method, the virtual opportunity keeps the Java stack unchanged, no longer presses the new stack in the thread's Java stack, the virtual machine simply dynamically connects and invokes the specified local method directly.
Where the method area and heap are shared by all threads in the virtual machine instance. When a virtual machine loads a class file, it parses the type information from the binary data contained in the class file, and then places the type information in the method area. When the program is running, the virtual opportunity puts all the objects created by the program at run time into the heap.
As with other run-time memory areas, the memory area that the local method stack occupies can be dynamically expanded or shrunk as needed.
3 Execution engine
In the Java Virtual Machine specification, the behavior of the execution engine uses the instruction set definition. The designer implementing the execution engine will decide how to execute the bytecode, which can be interpreted, just-in-time compiled, or directly executed using the instructions on the chip, or they can be mixed.
The execution engine can be understood as an abstract specification, a specific implementation, or a running instance. The abstract specification uses a set of instructions to specify the behavior of the execution engine. Specific implementations may use a variety of different technologies-including software, hardware, or tree technology. The execution engine as a run-time instance is a thread.
Each thread of a running Java program is an instance of a stand-alone virtual machine execution engine. From the start of the thread lifecycle to the end, it either executes the bytecode or executes the local method.
3.1 Instruction Set
The byte code stream of a method consists of a sequence of instructions from a Java virtual machine. Each instruction contains a single-byte opcode followed by 0 or more operands. The opcode represents the action that needs to be performed; the operand provides the Java Virtual machine with additional information needed to execute the opcode. When a virtual machine executes a directive, it may use the item in the current constant pool, the value in the local variable of the current frame, or the value at the top of the current frame operand stack.
The abstract execution engine executes one byte-code instruction at a time. Each thread of the program running in the Java Virtual machine (the execution engine instance) performs this operation. The execution engine obtains the opcode and, if the opcode has operands, obtains its operand. It performs the action specified by the opcode and following operands, and then obtains the next opcode. The process of executing the bytecode will continue until the thread completes, either by returning from its initial method or by not catching the thrown exception, which can mark the completion of the threads.
4 Local Method interface
The Java local interface, also called JNI (Java Native Interface), is intended for portability. The local method interface allows local methods to complete the following tasks:
Passing or returning data
Manipulating instance variables
Manipulating class variables or calling class methods
manipulating arrays
Lock the object of the heap
Load a new class
Throw an exception
To capture an exception thrown by a local method call Java method
Capturing asynchronous exceptions thrown by a virtual machine
Indicates that a garbage collector object is no longer needed