1. Preface-Why JVM again?
Many people think that distributed Java applications seem to be less concerned with Java virtual machines, not to mention distributed systems. A single-host JavaSE system does not need to thoroughly learn JVM, is there a JVM to execute. According to my experience, in large distributed systems, especially cloud computing service platforms, SAAS, and PAAS, applications must be highly efficient, when you are running a machine with a small configuration, the requirements for resources are demanding. Therefore, it is necessary to learn more about JVM. I have previously written an article about JVM loading classes at http://suhuanzheng7784877.iteye.com/blog/964784. Later I found that this was not enough. I still need to summarize other aspects of JVM runtime. We have a subtle effect on developing a distributed Java System, which is mainly used for review.
2. JVM Structure
What is the main responsibility of JVM? First, it is responsible for compiling the compiled java file into a class file; second, it is responsible for loading the existing class file; third, it is also responsible for executing the class; fourth, JVM is also responsible for memory allocation and recovery. This is why you do not need to manually write code to allocate resources and forcibly Recycle resources during code writing, there is a strong Manager-the JVM has done it for you; the JVM also needs to interact with the underlying operating system interface to complete multi-thread resource synchronization and concurrency mechanisms, so why can we implement a Runnable interface or integrate Thread to complete multi-threaded operations? On the surface, you have not done anything except writing some special classes. In fact, the JVM has quietly done so much for you.
Sun, oh, no, I can't change the port all the time. The Oracle Java specification JVM is as follows:
The Class file is loaded by the Class loader, And the JVM opens up memory space for it. The memory space is divided into four parts: Method Area, heap area, stack area, and local method stack area. The JVM starts a thread with a lower priority to run the Garbage Collector, which monitors and recycles the opened memory area at all times.
3. How does JVM compile Java code?
To run a class file, you need to compile the java file into a class file. How does JavaSDK compile it? Javac compiles the java source code into the class as follows:
1: analyze the input to the symbol table: Convert the string of the java file content into a keyword sequence, and then generate a tree-like content called an abstract syntax tree. The input to the symbol table means that the symbol that appears in the class is medium to the symbol table of the input class itself. The so-called symbol generally refers to the parent class and interface, because a non-argument constructor must be generated based on these symbols.
2: Processing annotation stage: Before JDK1.5, the JVM does not have this stage. However, after JDK1.5, the annotations we write in the Java class files must be processed and enhanced by JVM, for the time when the annotation is retained, see http://suhuanzheng7784877.iteye.com/blog/1054838.
Then, the validity is determined based on the abstract syntax tree and other information, and the semantic judgment, validation, and optimization of some codes of some columns are followed by the class file we see. In addition to bytecode, the class also includes information about JVM execution class:
Structure information: the file format version number of the class and the quantity and size of each part.
Metadata: metadata indicates the inheritance relationship, interface, declaration information, attributes, method declaration information, and constant pool information of the class.
Method information: including bytecode, exception handling table, and local variable area size
We use the decompilation tool to decompile the class source code we have previously written. Is it true that JDK has made some discrepancies with our source code when compiling this file? That is, it has optimized us.
4. How does JVM execute Java code?
There are three methods for JVM to execute class files: Interpretation and execution, compilation and execution, and reflection. Maybe you are more familiar with the third reflection execution, because this is also a relatively real positive coding experience for everyone, and the first two are all done by JVM, so it sounds strange.
1): Resolution execution
In JVM, parse and execute code that is not frequently executed. The internal principle of parsing and execution is very similar to the assembly language we have learned, JVM uses some self-defined commands (the assembly language also has some simple commands) to complete the code execution process, object-oriented is still procedural.
Parses and executes classes using four common commands. Invokestatic is used to call static methods. invokevirtual is used to call Instance Object methods. invokeinterface is used to call interface methods. invokespecial is used to call private methods and construct methods generated after the source code is compiled (that is, the class.
The following code
Java code
Import java. io. UnsupportedEncodingException;
Public class UTest {
Public static void main (String [] args) throws UnsupportedEncodingException {
String c = java.net. URLDecoder
. Decode ("% E4 % BA % A7 % E5 % 93% E6 % 8F % 8F % E8 % BF % B0 % E5 % 9F % 9F % E8 % B6 % 8A % E7 % 95% 8C ", "UTF-8 ");
System. out. println ("" + c );
}
}
After being compiled into a class, use javap-c UTest to view the bytecode content
Java code
Compiled from "UTest. java"
Public class UTest extends java. lang. Object {
Public UTest ();
Code:
0: aload_0 // load the first value of a local variable to the operand Stack
1: invokespecial #8; // Method java/lang/Object. "<init>" :() V // initialize the constructor
4: return
Public static void main (java. lang. String []) throws java. io. UnsupportedEncoding
Exception;
Code:
0: ldc #19; // String % E4 % BA % A7 % E5 % 93% 81% E6 % 8F % 8F % E8 % BF % B0 % E5 % 9F % 9F % E8 % B
6% 8A % E7 % 95% 8C // load the string value to the constant pool
2: ldc #21; // String UTF-8 // load the String value to the constant pool
4: invokestatic #23; // Method java/net/URLDecoder. decode :( Ljava/lang/Str
Ing; Ljava/lang/String;) Ljava/lang/String;
// Call the static method java.net. URLDecoder. decode
7: astore_1 // Add the value at the top of the stack in the operand stack to the local variable area.
8: getstatic #29; // Field java/lang/System. out: Ljava/io/PrintStream;
11: new #35; // class java/lang/StringBuilder
14: dup
15: ldc #37; // String
17: invokespecial #39; // Method java/lang/StringBuilder. "<init>" :( Ljava/la
Ng/String;) V
20: aload_1
21: invokevirtual #42; // Method java/lang/StringBuilder. append :( Ljava/lang
/String;) Ljava/lang/StringBuilder;
24: invokevirtual #46; // Method java/lang/StringBuilder. toString :() Ljava/l
Ang/String;
27: invokevirtual #50; // Method java/io/PrintStream. println :( Ljava/lang/St
Ring;) V
30: return
}
It is estimated that everyone is tired of reading and getting used to object-oriented thinking. When you look at this compilation-like language, it is really a headache and hard to bear. If it is not for JVM development, you can understand it. After all, you can understand the JVM running principle. It is a bit of thinking for us to write code.
Interpretation execution is slow, but it saves resources and memory because the data structure such as stack is used to collect, compile, and use commands, and the space utilization is obviously relatively frugal.
2): Compile and execute:
To improve performance, JDK can also compile and execute code, which is also called the Real-Time compiler. Generally, code with high execution frequency can be compiled and executed in a timely manner. Compilation and execution sacrifices some space resources, in exchange for the actual code block for optimizing bytecode compilation. That is to say, the code we write is optimizable In the JVM compiler, So it uses optimized compilation, adjust the original code to make better use of JVM resources. There are two main types of compilation and execution: client type and lightweight type; server type and heavyweight type.