Home >Java >javaTutorial >Introduction to knowledge points of Java Virtual Machine (JVM)
1. What is Java Virtual Machine
When you talk about Java Virtual Machine, you may mean:
1. Abstract Java Virtual Machine Specification
2. A specific Java Virtual Machine implementation
3. A running Java virtual machine instance
2. The life cycle of the Java virtual machine
A running Java virtual machine has a clear task: execute Java programs. It runs when the program starts executing and stops when the program ends. If you run three programs on the same machine, 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 directly accept a string array. When the program is executed, you must specify the class name that wraps the main() method to the Java virtual machine.
Main() method is the starting point of the program, and the thread in which it is executed is initialized as the initial thread of the program. All other threads in the program are started by him. There are two types of threads in Java: daemon threads and non-daemon threads. The daemon thread is a thread used by the Java virtual machine itself. For example, the thread responsible for garbage collection is a daemon thread. Of course, you can also set your own program as a daemon thread. The initial thread containing the Main() method is not a daemon thread.
As long as there are ordinary threads executing in the Java virtual machine, the Java virtual machine will not stop. If you have sufficient permissions, you can terminate the program by calling the exit() method.
3. Java Virtual Machine Architecture
The Java virtual machine specification defines a series of subsystems, memory areas, data types and usage guidelines. 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 of the Java virtual machine implementation.
Each Java virtual machine has a class loader subsystem (class loader subsystem), which is responsible for loading types (classes and interfaces) in the program and giving them unique names. Each Java virtual machine has an execution engine (execution engine) responsible for executing instructions contained in loaded classes.
The execution of the program requires a certain amount of memory space, such as bytecode, other additional information of the loaded class, objects in the program, method parameters, return values, local variables, processed intermediate variables, etc. The Java virtual machine stores all this information in data areas. Although every Java virtual machine implementation includes a data area, the Java virtual machine specification's provisions for the data area are very abstract. Many structural details are left to the Java virtual machine implementers. The memory structures on different Java virtual machine implementations vary widely. Some implementations may use a lot of memory, while others may use very little memory; some implementations may use virtual memory and others not. This relatively refined Java virtual machine memory specification allows the Java virtual machine to be implemented on a wide range of platforms.
Part of the data area is shared by the entire program, and other parts are controlled by separate threads. Each Java virtual machine contains a method area and a heap, which are shared by the entire program. After the Java virtual machine loads and parses a class, it saves the information parsed from the class file in the method area. Objects created when the program is executed are stored in the heap.
When a thread is created, it will be allocated its own PC register "pc register" (program counter) and Java stack (Java stack). When the thread does not use the native method, the PC register stores the next instruction executed by the thread. The Java stack saves the state when a thread calls a method, including local variables, parameters of the calling method, return values, and processed intermediate variables. The state when a native method is called is stored in native method stacks, possibly in registers or other non-platform-independent memory.
The Java stack is composed of stack frames (or frames). The stack block contains the status of Java method calls. When a thread calls a method, the Java virtual machine pushes a new block onto the Java stack. When the method ends, the Java virtual machine pops the corresponding block and discards it.
The Java virtual machine does not use registers to store the intermediate results of calculations, but uses the Java stack to store the intermediate results. This makes the Java Virtual Machine instructions more compact and makes it easier to implement the Java Virtual Machine on a device without registers.
In the Java stack in the picture, thread three in the PC register is gray because it is executing a local method and its next execution instruction is not saved in the PC register.
4. Data Types
All data used in the Java virtual machine has a certain data type, and the data types and operations are strictly defined in the Java virtual machine specification. Data types in Java are divided into primitive types (primitive types) and reference data types (reference types). Reference types depend on the actual object, but not the object itself. Primitive data types do not depend on anything; they represent the data themselves.
All primitive data types in the Java programming language are primitive data types of the Java virtual machine, except boolean. When the compiler compiles Java source code into its own code, it uses integer type (int) or byte type (byte) to represent Boolean type. The Java virtual machine uses the integer 0 to represent Boolean false and a non-zero integer to represent Boolean true. Boolean arrays are represented as byte arrays, although they may be stored in byte arrays or bit fields. in the heap.
Except for Boolean, other primitive types in the Java language are data types in the Java virtual machine. In Java, data types are divided into: integer byte, short, int, long; char and floating point type float, double. Data types in the Java language have the same scope on any host.
In the Java virtual machine, there is also a primitive data type return value type (returnValue) that cannot be used in the Java language. This type is used to implement "finally clauses" in Java programs. For details, see "Finally Clauses" in Chapter 18.
Reference types may be created as: class type, interface type, array type. They all refer to dynamically created objects. When a reference type refers to null, it means that no object is referenced.
The Java virtual machine specification only defines the range represented by each data type, but does not define the space occupied by each type during storage. How they are stored is left up to the implementer of the Java virtual machine. For more information about floating point types, see Chapter 14, "Floating Point Arithmetic".
TypeRange
byte8-bit signed two's complement integer (-27 to 27 - 1, inclusive)
short16-bit signed two's complement integer (-215 to 215 - 1, inclusive)
int32-bit signed two's complement integer (-231 to 231 - 1, inclusive)
long64-bit signed two's complement integer (-263 to 263 - 1, inclusive)
char16-bit unsigned Unicode character (0 to 216 - 1, inclusive)
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
5. Byte length
The smallest data unit word (word) in the Java virtual machine, its size is defined by the implementer of the Java virtual machine. But the size of one word must be enough to accommodate byte, short, int, char, float, returnValue, reference; two words must be enough to accommodate long, double. Therefore, the implementer of the virtual machine must at least provide a word smaller than 31 bits, but it is best to choose the most efficient word length on the specific platform.
At runtime, a Java program cannot determine the word length of the machine it is running on. Word length does not affect the behavior of the program, it is just a way of expression in the Java virtual machine.
6. Class loader subsystem
There are two types of class loaders in the Java virtual machine: primordial class loader and class loader objects. The original class loader is part of the Java virtual machine implementation, and the class loader object is part of the running program. Classes loaded by different class loaders are separated by different namespaces.
The class loader calls many other parts of the Java virtual machine and many classes in the java.lang package. For example, the class loading object is an instance of the java.lang.ClassLoader subclass. The methods in the ClassLoader class can access the class loading mechanism in the virtual machine; each class loaded by the Java virtual machine will be represented as a java.lang.Class Instance of class. Like other objects, class loader objects and Class objects are stored in the heap, and loaded information is stored in the method area.
1. Loading, Linking and Initialization
The class loading subsystem is not only responsible for locating and loading class files, it also does many other things according to the following strict steps: (specific information See "Class Life Cycle" in Chapter 7)
1), Loading: Find and import binary information of the specified type (class and interface)
2), Connection: Verify, prepare and parse
① Verification: Ensure the correctness of the imported type
② Preparation: Allocate memory for the type and initialize it to the default value
③ Parsing: Parse character references into direct drinking
3), Initialization: Call Java code, initialize The class variable is an appropriate value
2. The Primordial Class Loader
Each Java virtual machine must implement a primitive class loader that can load those that comply with the class file format and are trusted kind. However, the specification of the Java virtual machine does not define how to load classes, which is left to the Java virtual machine implementer to decide. For a type with a given type name, the original loader must find the file with the type name plus ".class" and load it into the virtual machine.
3. Class loader object
Although the class loader object is part of the Java program, the three methods in the ClassLoader class can access the class loading subsystem in the Java virtual machine.
1), protected final Class defineClass(...): Use this method to access a byte array and define a new type.
2), protected Class findSystemClass(String name): Load the specified class. If it has been loaded, return directly.
3), protected final void resolveClass(Class c): The defineClass() method only loads a class. This method is responsible for subsequent dynamic connection and initialization.
For specific information, see Chapter 8 "The Linking Model".
4. Namespace
When multiple class loaders load the same class, in order to ensure the uniqueness of their names, the identifier of the class loader that loads the class needs to be added before the class name. For specific information, see Chapter 8 "The Linking Model".
7. The Method Area
In the Java virtual machine, the information of the loaded type is stored in the method area. The organization form of this information in memory is defined by the implementer of the virtual machine. For example, if the virtual machine works on a "little-endian" processor, it can save the information in the "little-endian" format. Although In Java class files they are saved in "big-endian" format. Designers can store data in a representation format that is most suitable for the local machine to ensure that the program can execute at the fastest speed. However, on a device with only a small amount of memory, the implementer of the virtual machine will not occupy a large amount of memory.
All threads in the program share a method area, so the method of accessing method area information must be thread-safe. If you have two threads loading a class called Lava, only one thread is allowed to load this class, and the other must wait.
When the program is running, the size of the method area is variable, and the program can be expanded while the program is running. Some Java virtual machine implementations can also customize the initial size, minimum and maximum values of the method area through parameters.
The method area can also be garbage collected. Because the content in the program is dynamically loaded by the class loader, all classes may become unreferenced. When a class becomes this state, it may be garbage collected. Classes that are not loaded include two states, one is really not loaded, and the other is the "unreferenced" state. See The Lifetime of a Class in Chapter 7 for details.
1. Type Information (Type Information)
Each loaded type will save the following information in the method area in the Java virtual machine:
1), the full name of the type (The fully qualified name of the type)
2), the fully qualified name of the typeís direct superclass (unless there is no parent type, or the Frey form is java.lang.Object) (The fully qualified name of the typeís direct superclass)
3), Whether the type is a class or an interface (Whether or not the type is a class)
4), type modifiers (public, private, protected, static, final, volatile, transient, etc.) ( The typeís modifiers)
5), An ordered list of the fully qualified names of any direct superinterfaces)
The data structure saved by the full name of the type is defined by the virtual machine implementer. In addition, the Java virtual machine also stores the following information for each type:
1), the constant pool for the type (The constant pool for the type)
2), and type field information (Field information)
3), type method information (Method information)
4), all static class variables (non-const) information (All class (static) variables declared in the type, except constants)
5) , A reference to class ClassLoader
6), A reference to Class Class
1), the constant pool for the type (The constant pool for the type)
All types saved in the constant pool are an ordered set of constants, including direct constants (literals) such as strings, integers, and floats. Dot constants, and symbolic references to types, fields, and methods. Each constant saved in the constant pool has an index, just like a field in an array. Because the constant pool stores character references to types, fields, and methods used by all types in the constant pool, it is also the main object of dynamic connection. See Chapter 6, "The Java Class File" for details.
2), type field information (Field information)
Field name, field type, field modifiers (public, private, protected, static, final, volatile, transient, etc.), fields defined in the class order.
3), type method information (Method information)
Method name, method return value type (or void), number of method parameters, type and their order, field modifiers (public, private, protected, static, final, volatile, transient, etc.), the order in which the methods are defined in the class
If it is not abstract and local, this method also needs to save the bytecode of the method and the size of the operand stack of the method and the size of the local variable area (details will be available later), exception list (see Chapter 17 "Exceptions" for details.)
4), class (static) variables (Class Variables)
Class variables are Shared by all instances of a class, it can be accessed even without going through an instance of the class. These variables are bound to the class (rather than to instances of the class), so they are part of the class's logical data. Before the Java virtual machine uses this class, you need to allocate memory for the class variable (non-final).
The processing method of constants (final) is different from this class variable (non-final). When each type uses a constant, it will copy it to its own constant pool. Constants are also stored in the method area like class variables, except that they are stored in the constant pool. (Probably, class variables are shared by all instances, while constant pool is unique to each instance). Non-final class variables are saved as part of the data for the type that declares them, while final constants are saved as part of the data for any type that uses them. For details, see Chapter 6 "The Java Class FileThe Java Class File"
5), A reference to class ClassLoader
Every type loaded by the Java virtual machine must be saved by the virtual machine Whether this type is loaded by the original class loader or the class loader. Types loaded by a class loader must maintain a reference to the class loader. This information is used when the class loader connects dynamically. When a class references another class, the virtual machine must save that the referenced type is loaded by the same class loader. This is also the process of the virtual machine maintaining different namespaces. For details, see Chapter 8 "The Linking Model"
6), A reference to class Class (A reference to class Class)
The Java virtual machine creates an instance of the java.lang.Class class for each loaded type. . You can also use the Class class method:
public static Class forName(String className) to find or load a class and obtain an instance of the corresponding Class class. Through this instance of the Class class, we can access the information in the method area of the Java virtual machine. For details, refer to the JavaDoc of the Class class.
2. Method Tables
In order to access all data stored in the method area more efficiently, the storage structure of these data must be carefully designed. In all method areas, in addition to saving the original information above, there is also a data structure designed to speed up access, such as a method list. For each loaded non-abstract class, the Java virtual machine will generate a method list for them. This list stores references to all instance methods that may be called by this class, and reports errors to methods called in the parent class. For details, see Chapter 8 "The Linking Model" 8. Heap
When a Java program creates an instance or array of a class, it allocates memory for the new object 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 method to release unreferenced objects. It may also move objects around to reduce heap fragmentation. Garbage collection is not strictly defined in the Java virtual machine specification, but it is defined that a Java virtual machine implementation must manage its own heap in some way. See Chapter 9 "Garbage Collection" for details.
2. Object Storage Structure (Object Representation)
The specification of the Java virtual machine does not define how objects are stored in the heap. Each object mainly stores object variables defined in its class and parent class. For a reference to a given object, the virtual machine must quickly locate the data of this object. In addition, a method must be provided to reference the method object data through the object, such as the reference of the object in the method area, so the data saved by an object often contains some form of pointer to the method area.
One possible heap design is to divide the heap into two parts: a reference pool and an object pool. A reference to an object is a local pointer to a reference pool. Each entry in the reference pool contains two parts: a pointer to the object data in the object pool and a pointer to the object class data in the method area. This design can facilitate the defragmentation of the Java virtual machine heap. When the virtual machine moves an object in the object pool, it only needs to modify the pointer address in the corresponding reference pool. But each time you access the object's data, you need to process the pointer twice. The figure below demonstrates this heap design. The HeapOfFish Applet in Chapter 9, "Garbage Collection," demonstrates this design.
Another heap design is: the reference of an object is an offset pointer pointing to a pile of data and pointing to the corresponding object. This design facilitates object access, but object movement becomes extremely complicated. The following figure demonstrates this design
When the program attempts 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. A similar thing will be done when the program uses the instanceof statement. When a program calls a method of an object, the virtual machine needs to perform dynamic binding, and it must determine which type of method to call. This also requires the above judgment.
No matter which design the virtual machine implementer uses, he may save information similar to a method list for each object. Because it can increase the speed of object method calls, it is very important to improve the performance of virtual machines. However, there is no requirement in the virtual machine specifications that similar data structures must be implemented. The diagram below depicts this structure. The figure shows all the data structures associated with an object reference, including:
1), a pointer to type data
2), and an object's method list. A method list is an array of pointers to all possible methods of an object that may be called. Method data includes three parts: the size of the opcode stack and the local variable area of the method stack; the bytecode of the method; and the exception list.
Each object in the Java virtual machine must be associated with a lock (mutex) used to synchronize multiple threads. At the same time, only one object can hold the lock of this object. When a person owns the lock of this object, he can apply for the lock multiple times, but he must also release the lock a corresponding number of times before he can actually release the object lock. Many objects are not locked throughout their lifetime, so this information only needs to be added when needed. Many Java virtual machine implementations do not include "lock data" in the object's data, and only generate the corresponding data when needed. In addition to implementing object locking, each object is also logically associated with a "wait set" implementation. Locking helps threads process shared data independently without interfering with other threads. "Wait set" helps group threads collaborate to accomplish the same goal. "Wait set" is often implemented through the wait() and notify() methods of the Object class.
Garbage collection also requires information about whether objects in the heap are associated. The Java Virtual Machine Specification states that garbage collection runs the finalizer method of an object once, but allows the finalizer method to re-reference the object. When the object is not referenced again, there is no 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 "Garbage Collection" in Chapter 9
3. Storage of Arrays (Array Representation)
In Java, an array is a complete object. It is saved in the heap like an object. There is a reference to an instance of the Class class. All arrays of the same dimension and type have the same Class, and the length of the array is not considered. The name corresponding to the Class is expressed as a dimension and type. For example, the Class name of an integer data is "[I", the Class name of a byte-type three-dimensional array is "[[[B", and the Class name of two-dimensional object data is "[[Ljava.lang.Object".
Multidimensional arrays are represented as arrays of arrays, as shown below:
Arrays must store the length of the array, the data of the array, and some references to object array type data in the heap. Through an array reference, the virtual machine should be able to obtain the length of an array, access specific data through indexing, and call methods defined by Object. Object is the direct parent class of all data classes. See Chapter 6, "Class Files" for more information.
9. PC Register (Program Counter) (The Program Counter)
A program counter will be created when each thread starts execution. The program counter is only one word long, so it can hold a local pointer and returnValue. When the thread executes, the program counter stores the address of the instruction being executed. This address can be a local pointer or an offset pointer starting from the method bytecode. If a native method is executed, the program counter value is not defined.
10. The Java Stack
When a thread starts, the Java virtual machine creates a Java stack for it. The Java stack uses some discrete frame classes to record the status of threads. Java virtual machine heap There are only two operations on the Java stack: pushing and popping 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 that defines the current method is called the current class, and the constant pool of the current class is called the current constant pool. When a thread executes, the Java virtual machine keeps track of the current class and the current constant pool. But when a thread operates on the data stored in the frame, it only operates on the data of the current frame.
When a thread calls a method, the virtual machine generates a new frame and pushes it into the thread's Java stack. This new frame becomes the current frame. When the method executes, it uses the current frame to save the method's parameters, local variables, intermediate structures, and other data. Methods have two ways to exit: normal exit and abnormal exit. No matter which way the method is launched, the Java virtual machine will pop up and discard the frame of the method, and the frame of the previous method becomes the current frame.
All data saved in the frame can only be accessed by the thread that owns it. Threads cannot access data in the stacks of other threads. Therefore, when accessing local variables of a method, there is no need to consider multi-thread synchronization.
Like the method area and heap, the Java stack does not require continuous memory space. It can be stored in a dispersed memory space or on the heap. The specific data and length of the stack are defined by the implementer of the Java virtual machine. Some implementations may provide methods for performing stack maximization and minimization.
11. The Stack Frame
The stack frame contains three parts: local variables, operand stack and frame data. The sizes of local variables and operand stacks are measured in words, and they are determined during compilation. The size of the frame data depends on different implementations. When the program calls a method, the virtual machine obtains the size of the local variables and operand stack from the class data, creates an appropriate size and frame, and then pushes it onto the Java stack.
1. Local Variables
Local variables are organized as an array counting from 0 in the Java stack frame. The instruction obtains the corresponding value from the local variable area by providing their index. Int, float, reference, returnValue occupy one word, byte, short, char are converted into int and then stored, long and doublel occupy two words. The
directive obtains the value of long or double by providing the first of two word indices. For example, if a long value is stored at index 3 or 4, the instruction can use 3 to obtain the long value.
The local variable area contains method parameters and local variables. The compiler places method parameters at the front of the array in the order in which they are declared. However, the compiler can arrange local variables arbitrarily in the local variable array, and even two local variables can share a common address. For example, when two local variables are in two non-overlapping areas, like loop variables i,j .
The implementer of the virtual machine 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 doublel.
2. Operand Stack (Operand Stack)
Like local variables, the operand stack is also organized into an array in word units. But it is not accessed through index like local variables, but through push and pop values. If one instruction pushes a value onto the stack, the next instruction can pop and use that value.
Unlike the program counter, the operand stack cannot be directly accessed by instructions. Instructions can directly access the operand stack. The Java virtual machine is stack-based rather than register-based because its instructions obtain operands from the stack rather than from the same register. Of course, instructions can also get operands from other places, such as the opcode after the instruction, or the constant pool. But Java virtual machine instructions mainly obtain the operands they need from the operand stack.
The Java virtual machine treats the operand stack as a work area. Many instructions pop the value from the operand stack first, and then push the result back to the operand stack after processing. The execution process of an add instruction is shown in the figure below: first execute the iload_0 and iload_1 instructions to take the two numbers that need to be added from the local method area and push them to the operand stack; then execute the iadd instruction and now pop Output two values, add them, and push the result into the operand stack; finally execute the istore_2 instruction, pop out the result, and assign it to the local method area.
3. Frame Data
In addition to processing local variables and operand stacks, java stack frames also include data needed to support constant pools, method return values and exception distribution. They are saved in frame data middle.
When the virtual machine encounters an instruction that uses a reference to the constant pool, it will access the required information through the pointer to the constant area in the frame data. As mentioned earlier, references in the constant area are symbolic references at the beginning. Even when the virtual machine checks these references, they are character references. So the virtual machine needs to convert this reference at this time.
When a method returns normally, the virtual machine needs to rebuild the stack frame of the method that called this method. If the executed method has a return value, the virtual machine needs to push this value into the operand stack of the calling method.
The frame data also contains a reference to the exception table used by the virtual machine to handle exceptions. The exception table defines a section of bytecode protected by a catch statement. Each individual in the exception table also contains the range of bytecodes that need to be protected, and the location of the bytecode that needs to be executed when the exception is caught. When a method throws an exception, the Java virtual machine uses the exception table to determine how to handle the exception. If the virtual machine finds a matching catch, it will transfer control to the catch statement. If no matching catch is found, the method will return abnormally, and then continue the process in the calling method.
In addition to the above three uses, frame data may also contain some implementation-dependent data, such as debugging information.
12. Local method stack
The local method area depends on different implementations of the virtual machine. The implementer of the virtual machine can decide which mechanism to use to execute native methods.
Any Native Method Interface uses some form of native method stack.
13. Execution engine
The core of a java virtual machine implementation is the execution engine. In the Java Virtual Machine Specification, the execution engine is described as a sequence of instructions. For each directive, the specification describes what they should do, but not how to do it.
1. Instruction set
In the Java virtual machine, the bytecode stream of a method is a sequence of instructions. Each instruction consists of a byte operation code (Opcode) and possible operands (Operands). The opcode tells what to do, and the operands provide some additional information that may be needed to execute the opcode. An abstract execution engine executes one instruction at a time. This process occurs in every thread of execution.
Sometimes, the execution engine may encounter an instruction that requires calling a local method. In this case, the execution engine will try to call the local method, but when the local method returns, the execution engine will continue to execute the bytecode stream. the next instruction. Native methods can also be seen as an expansion of the instruction set in the Java virtual machine.
Deciding which instruction to execute next is also part of the execution engine's work. The execution engine has three methods to obtain the next instruction. Most instructions will execute the instructions that follow them; some instructions like goto and return will determine their next instruction when they are executed; when an instruction throws an exception, the execution engine determines the next instruction by matching the catch statement. The instruction that should be executed.
Platform independence, network mobility, and security influence the design of the Java virtual machine instruction set. Platform independence is one of the main influencing factors in instruction set design. The stack-based structure allows the Java virtual machine to be implemented on more platforms. Smaller opcodes and compact structure allow bytecode to utilize network bandwidth more efficiently. One-time bytecode verification makes bytecode more secure without affecting too much performance.
2. Execution technology
Many execution technologies can be used in the implementation of Java virtual machines: interpreted execution, just-in-time compiling, hot-spot compiling, and native execution in silicon.
3. Threads
The Java virtual machine specification defines a threading model for implementation on more platforms. One goal of the Java threading model is to take advantage of native threads. Using local threads allows the threads in a Java program to be executed simultaneously on a multi-processor machine.
One of the costs of the Java threading model is thread priority. A Java thread can run at a priority level of 1-10. 1 is the lowest and 10 is the highest. If the designer had used native threads, they might have mapped these 10 priorities to local priorities. The Java virtual machine specification only defines that threads with higher priority can get some CPU time, and threads with lower priority can also get some CPU time when all high-priority threads are blocked, but there is no guarantee: low priority The thread cannot get a certain amount of CPU time when the high-priority thread is not blocked. Therefore, if you need to cooperate between different threads, you must use "synchronization (synchronizatoin)".
Synchronization means two parts: object locking and thread waiting and activation (thread wait and notify). Object locks help threads remain free from interference from other threads. Thread waiting and activation allow different threads to cooperate.
In the specification of the Java virtual machine, Java threads are described as variables, main memory, and working memory. Each instance of the Java virtual machine has a main memory, which contains all program variables: objects, arrays, and class variables. Each thread has its own working memory, and it keeps copies of the variables it may use. Rules:
1), copy the value of the variable from the main 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 variables in main memory in any order. In order to ensure the correct execution of multi-threaded programs, a synchronization mechanism must be used.
14. Native Method Interface
The implementation of the Java virtual machine does not have to implement the native method interface. Some implementations may not support native method interfaces at all. Sun's native method interface is JNI (Java Native Interface).
15. The Real Machine
16. Mathematical Method: Simulation (Eternal Math: A Simulation)
The above is the detailed content of Introduction to knowledge points of Java Virtual Machine (JVM). For more information, please follow other related articles on the PHP Chinese website!