I. Preface
The execution engine of the physical machine is run directly on the physical hardware such as CPU, operating system, instruction set, but for the virtual machine, his execution engine is implemented by himself. The execution engine has a uniform appearance (Java Virtual machine specification), and different types of virtual machines follow this specification, enter bytecode files, parse bytecode processing, and then output the results.
Two. Runtime stack frame structure
1. Stack frame concept
Stack frames are used to support the data structures of method invocations and executions, including local variable tables, operand stacks, dynamic joins, and method return addresses.
- The local variable table size (max_locals), the stack frame depth is determined at compile time, and is written to the code attribute;
- All bytecode instructions run by the execution engine operate on the current stack only;
2. Local variable table
The local variable table stores the method parameters and local variables defined within the method.
- Slot (variable slot): Local variable table capacity of the smallest unit, can hold 32-bit data type;
- Refrence
- directly or indirectly find the starting address index of the object in the "heap memory" of the data;
- directly or indirectly find the type information stored in the method area of the data type to which the object belongs;
- The local variable table is built on the thread's stack, so manipulating two contiguous slots for atomic operations does not cause a data security problem, but if it is 64 bits, it is not allowed to access one of them in any way alone;
- This: the instance method (non-static) defaults to the first (No. 0-bit index) slot for the current object's own reference;
- Slot Reuse:
- The current bytecode of the PC counter is outside the scope of a variable, the slot of this variable can be given to other variables to use;
- Affects the normal Java garbage collection mechanism;
- Null: Because of the reason for the above slot reuse, when a local variable in the method domain defines a variable that is not actually used by the large memory, then the subsequent code is a time-consuming operation, and the time to assign null is of great significance. Because once triggered, this part of the slot can be reused. It looks like a "class GC" operation inside a method area. However, it is not always necessary to assign null. It is the most elegant way to control the variable payback time with the appropriate variable scope, and the null value operation is eliminated after the JIT-compiled optimization, so it doesn't make any sense.
- Initial values: Unlike class variables, the local variable system does not automatically assign initial values, so no assignment is unusable and compilation fails. Even though the byte-code verification phase is checked out, the class load fails;
3. Operand stack (Operand stack)
- Operation Stack, after-in first-out;
- Maximum depth: Max_stacks in the code attribute table;
- The 32-bit data type has a stack capacity of 1 and 64-bit capacity of 2;
- The data type of the stack element must be consistent with the stack directive
- There can be a portion of overlap between two stack frames, sharing the data so that the extra parameters are duplicated when the method call is avoided.
- The Java Virtual machine Interpretation execution engine is also: the stack-based execution engine;
4. Dynamic connection (linking)
The invocation of a method in a bytecode is a parameter of the specified method in a constant pool
- Static parsing: This symbol is either a class loading phase or a direct reference to the first use of initialization
- Dynamic connection: Another part is converted to a direct reference at run time
5. Method return Address
- Exit:
- Normal exit: Encountered the return bytecode instruction;
- Exception exit: This method does not have a matching exception in the exception table;
- After exiting, the local variable table and the Operation stack of the upper method are restored, and the return value is pressed into the upper caller's stack with the return value;
Three. Method invocation
Definition: Determine the version of the called method
1. Analysis
- The compiler indicates that the runtime is immutable. The invocation of such a method becomes parsed and parsed during the class loading phase.
- Static methods, private methods, instance constructor methods, and parent methods conform to the above criteria. Features are:
- Can only be called by invokestatic and invokespecial directives
- Cannot be inherited or rewritten, and a version has been determined at compile time.
- When the class loads, the compliance reference is resolved to a direct reference to the method.
- Non-virtual methods (note that final is also a non-virtual method, others are virtual methods)
2. Static Dispatch
- Concept: Locating the execution version of a method according to a static type
- Typical delegate: Overloading of methods (method names are the same, parameter types are different)
- Occurrence time: Compile phase
3. Dynamic Dispatch
- Concept: When calling Invokevirtual, the class method symbols in the constant pool are parsed to different direct references.
- Typical representation: rewriting, an important manifestation of polymorphism
- Process:
- Execute invokevitual directive
- Find method in virtual method table (class load phase, virtual method table initialized after class variable initialization), no up parent class to find
- Method Volume: The recipient of the method and the generic name of the method parameter
- Single dispatch and multiple dispatch:
- Only one parcel is chosen as the basis for the method, called a single dispatch. Multiple, which is called multi-Dispatch.
- The current Java is a static multi-dispatch, dynamic single-Dispatch language;
Four. Dynamic Language support
Features: variable no type, variable value only type
Invoke Package: Java implements dynamic language new package
Five. Instruction set
- Stack-based instruction set
- Process: In-stack, compute, stack
- Advantages:
- Portability, not dependent on hardware
- Compact Code
- Disadvantages:
- Slow speed
- Produce quite a number of instructions
- Frequent memory accesses
- Register-based instruction set
Six. Method inline
- The way to inline the method is to avoid the actual method invocation by copying the code of the "target method" into the method that originated the call.
- Inline eliminates the cost of method calls and establishes a good foundation for other optimization methods.
- When the compiler is inline, it is directly inline if it is a non-virtual method. If a virtual method is encountered, the current program will be queried whether there are multiple target versions to choose from, if the query results have only one version, it can also be inline, but this inline is a radical optimization, need to reserve an escape gate (slow Path when the guard condition is not established), known as the Guardian inline.
- Inline optimized code can be used all the time if the virtual machine has not been loaded during the subsequent execution of the program to discover classes that change the inheritance of the recipient of this method. Otherwise, you need to discard the compiled code, go back to the interpretation state, or recompile
Seven. Escape analysis
The basic behavior of escape analysis is to analyze the object dynamic scope: When an object is defined inside a method, it may be referenced by an external method, which is called a method escape. accessed by an external thread, called a thread escape.
What optimizations can be made if an object does not escape to a method or thread?
- On-Stack allocation: General objects are allocated in the Java heap, and for each thread it is shared and visible, so long as the reference to the object is held, the object data stored in the heap can be accessed. However, garbage collection and collation can be time-consuming, and if an object does not escape the method, allowing the object to allocate memory on the stack, the memory space occupied by the object can be destroyed with the stack frame. If you can use stack allocation, the large number of objects will be automatically destroyed as the method ends, and the pressure on garbage collection will be much smaller.
- Synchronous elimination: Thread synchronization itself is a time-consuming process. If the escape analysis can determine that a variable does not escape the outgoing thread, then the read and write of this variable will not compete, and the synchronization measures can be eliminated.
- Scalar substitution: The object is not created and several of its members are created directly to be replaced by the member variables used by the method.
Eight. Summary
In the previous we have learned that the stack frame, the method area of memory when the thread private, this article in more detail about how to find and execute the method. Java Virtual Machine specification: Input byte code, parse byte code processing, output result. First, the stack frame contains the local variable table, the operand stack, the dynamic connection, and the method return address. The methods in bytecode are specified by the symbols in the constant pool, some compile parsing determines, and some run lines are converted to direct references. First, remember that the JVM is a stack-based execution engine. The stack has a first-in-a-out feature, and the execution engine's instruction executes only the current stack. While the local variable table stores the variable information required in the method, it is stored in slot, and after the operation domain is exceeded, the original memory area can be used by other local variables, like "recycle". Then, remember that Java is a static multi-dispatch, dynamic single-Dispatch language. Static dispatch, such as overloading of methods. You can determine which method to invoke by using the different parameters of the method, and this will be done in the compilation phase. Dynamic dispatch, such as the override of a method. When executing a method, there is a virtual method table. This table search, I have to carry out their own, do not look up to the parent class. This is the important principle of the Java implementation polymorphism. Java also has an invoke package that supports dynamic languages, usually with less.
Deep understanding of Java Virtual Machine 06--virtual machine bytecode execution engine