Alibaba's architect explains how virtual machines work

1. Class loader

First, let's take a look at the execution process of a java program.

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

From this block diagram it is easy to get a general understanding of how a java program works. First, you write the java code and save it to the hard disk. Then you type in the command line

[java] view plain copy

  1. javac YourClassName.java

At this point, your java code is compiled into bytecode (.class). If you are in Eclipse IDE or other development tools, when you save the code, the development tools have already completed the above compilation work for you, so You can see the class file in the corresponding directory. The class file at this time is still saved on the hard disk, so when you run the command line

[java] view plain copy

  1. java YourClassName

This completes the work in the red box above. The JRE loader reads the class file from the hard disk and loads it into the memory area allocated by the system to the JVM--Runtime Data Areas. Then the execution engine interprets or compiles the class file and converts it into machine code for a specific CPU , the CPU executes the machine code, and the whole process is completed.

Next, let's focus on what is a class loader? How does it work?

First look at some features of the loader, a bit abstract, but always helpful.

》》Hierarchical structure

Class loaders are organized into a hierarchical relationship, that is, a parent-child relationship. Among them, Bootstrap is the father of all class loaders. As shown below:

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

--Bootstrap class loader:

When running the java virtual machine, this class loader is created, it loads some basic java API, including the Object class. It should be noted that this class loader is not written in Java language, but written in C/C++.

--Extension class loader:

This loader loads some extended classes beyond the basic API, including some classes related to security performance. (I don’t know much about it at present, I can only say it in general terms, and I will explain it in detail later)

--System Class Loader:

It loads classes in your application, ie classes configured on your classpath.

--User-Defined Class Loader:

This is a custom loader defined by the developer by extending the ClassLoader class to load some classes defined by the programmer.

》》Delegation Mode

Looking at the above hierarchy carefully, when the JVM loads a class, the lower loader will delegate the task to the upper class loader, and the upper loader checks whether the class has been loaded in its namespace, and if so Load, use this class directly. If not loaded, continue to delegate up until the top. After checking, load them in reverse order. If the Bootstrap loader can't find the class, it delegates down until it finds the class file. For a particular class loader, a Java class can only be loaded once, that is to say, in the Java virtual machine, the full class identifier is (classLoader, package, className). A mine can be loaded by different class loaders.

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

To give a specific example, now I have a self-defined class MyClass that needs to be loaded. If it is not specified, it is usually loaded by App (System). After receiving the task, System checks whether there is already this class in its own library, and then delegates it to Extension after finding that it does not. Extension performs the same check and finds that it still does not continue to delegate. The top-level Boots finds that there is no such class in its own library, so According to its path (Java core class library, such as java.lang), I tried to load it, but I couldn't find the MaClass class, so I had to (people are optimistic about you, let it be done by you, you can't do anything, you have to leave it to others) and delegate it to Extension, Extension is looking for its own path (JAVA_HOME/jre/lib/ext), or not found, continue down, at this time, the System loader looks for the classpath path, finds it, and loads it into the Java virtual machine.

Now suppose we put this class in the path of JAVA_HOME/jre/lib/ext (equivalent to handing it over to the Extension loader to load), and according to the same rules, the MyClass class is finally loaded by the Extension loader. See, unify each Classes are loaded into the JVM twice, but each time by a different ClassLoader.

》》Visibility Restrictions

The lower loader can see the classes in the upper loader, but not vice versa, that is to say, the delegate can only go from bottom to top.

》》No unloading of classes is allowed

A class loader can load a class, but it cannot unload a class. But class loaders can be deleted or created.

When the class is loaded, the JVM continues to complete other tasks according to the following figure:

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

The steps in the block diagram are briefly described as follows:

Loading: The class loading described earlier in the article loads the Class file in the file system into the JVM memory (running data area)

Verifying: Check whether the loaded class file conforms to the Java specification and the virtual machine specification.

Preparing: Allocate the required memory for this class, and determine the data structures required for the properties, methods, etc. of this class. (Prepare a data structure that assigns the memory required by classes and indicates the fields, methods, and interfaces defined in the class.)

Resolving: Change all symbolic references in the constant pool of this class to direct references. (not very understanding)

Initialing: Initialize the local variables of the class, assign values ​​to the static fields, and execute the static initialization block at the same time.

So, what exactly does Class Loader do when loading classes?

To understand the details of this, we must first introduce the operational data area in detail.

2. Operation data area

Runtime Data Areas: When running a JVM example, the system will assign it a memory area (the size of this memory area can be set), which is managed by the JVM itself. A block is allocated from this piece of memory to store some operational data, such as objects created, parameters passed to methods, local variables, return values, and so on. This part is called the running data area. The running data area can be divided into 6 large blocks: Java stack, program counter register (PC register), native method stack (Native Method Stack), Java heap, method area, and Runtime Constant Pool. The running constant pool should belong to the method area, but because of its importance, the JVM specification describes it independently. Among them, the first three areas (PC register, Java stack, native method stack) are owned by each thread alone, and the latter three are shared by all threads in the entire JVM instance. The six blocks are shown below:

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

  • 》PC counter:

  • Each thread has a PC counter. When the thread starts, the PC counter is created. This counter stores the address of the bytecode instruction (JVM instruction) currently being executed.

  • 》Java stack:

  • Similarly, the Java stack is owned by each thread and created when the thread starts. This stack stores a series of stack frames, and the JVM can only perform two operations: push and pop. Whenever a method is called, the JVM pushes a stack frame into the stack, and pops the stack frame when the method returns. If an exception occurs during method execution, you can call methods such as printStackTrace to view the stack. The schematic diagram of the stack is as follows:

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

OK. Now let's take a closer look at what's in each stack frame. It is easy to see from the schematic diagram that each stack frame contains three parts: the local variable array, the operand stack, and the constant pool reference of the class to which the method belongs.

"Local (local) variable array:

In the local (local) variable array, the reference to the object to which the method belongs, the parameters passed to the method, and the local variables are stored in order starting from 0. for example:

[java] view plain copy

  1. publicvoid doSomething(int a, double b, Object o) {

  2. ...

  3. }

The contents of the local variables stored in the stack frame of this method are:

[java] view plain copy

  1. 0: this

  2. 1: a

  3. 2,3:b

  4. 4:0

Look carefully, where b of type double requires two consecutive indices. When the value is retrieved, the value in the index of 2 is retrieved. If it is a static method, the 0th of the array does not store this reference, but directly stores the passed parameters.

"Operand stack:

Some intermediate variables during method execution are stored in the operand stack, and the JVM pushes or pops these variables during method execution. In fact, the operand stack is where the method really works. When the method is executed, the local variable array and the operand stack exchange data according to the method definition. For example, when the following code is executed, the operand stack looks like this:

[java] view plain copy

  1. int a = 90;

  2. int b = 10;

  3. int c = a + b;

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

Note that in this figure, the level of the operand stack is at the top, so the 100 that was pushed first is at the top. It can be seen that the operand stack is actually a temporary data storage area, which stores some intermediate variables. When the method is over, the operand stack will be gone.

》Data reference in stack frame:

In addition to the local variable array and operand stack, the stack frame also needs a reference to a constant pool. When the JVM executes the data that needs the constant pool, it accesses the constant pool through this reference. The data in the stack frame is also responsible for handling method returns and exceptions. If returned by return, the method's stack frame is popped from the Java stack. If the method has a return value, push the return value onto the operand stack of the method that called the method. In addition, a reference to the possible exception table in this method is also stored in the data area. The following example is used to illustrate:

[java] view plain copy

  1. class Example3C{

  2. publicstaticvoid addAndPrint(){

  3. double result = addTwoTypes(1,88.88);

  4. System.out.println(result);

  5. }

  6. publicstaticdouble addTwoTypes(int i, double d){

  7. return i+d;

  8. }

  9.  
  10. }

When the above code is executed, the Java stack looks like this:

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

Take some time to study the image above. It should also be noted that the bottom of the stack is at the top, the stack frame of the addAndPrint method is pushed first, and then the stack frame of the addTwoTypes method is pushed. There is an error in the text description on the far right of the above figure. It should be that the execution result of addTwoTypes is stored in the operand stack of addAndPrint.

》》Local method stack

When a program calls a native method (such as C or C++ code) through JNI (Java Native Interface), a corresponding stack is established according to the language type of the native method.

》》Method area

Method areas are shared by all threads in a JVM instance and are created when a JVM instance is started. It is used to store the run-time constant pool, information about fields and methods, static variables, and bytecode for classes and methods. Different JVM implementations differ in how they implement method areas. Oracle's HotSpot is called the permanent area (Permanent Area) or permanent generation (Permanent Generation).

》》Running constant pool

This area holds class and interface constants, in addition to all references to methods and fields. When a method or field is referenced, the JVM looks up the actual address of the method and field in memory by running these references in the constant pool.

》》Heap

The heap stores objects or instances created by the program. This area has a large impact on the performance of the JVM. It is this area of ​​memory that the garbage collection mechanism deals with.

Therefore, the loading of the class loader is actually to load the java bytecode into the JVM memory according to the compiled Class file, and complete the initialization of the running data for the execution engine to execute.

3. Execution Engine

After the class loader loads the bytecode into memory, the execution engine reads the Java bytecode based on the Java bytecode instructions. The problem is that the current java bytecode machine cannot read it, so we must find a way to convert the bytecode into platform-dependent machine code. This process can be performed by an interpreter or a just-in-time compiler (JIT Compiler).

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

I recommend an architect knowledge system to everyone

In fact, many things are very simple:

Engineering Topics

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

Microservices Topics

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

As Ali's p7, of course, you must understand the Double Eleven project;

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

To be able to fully understand the source code

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

Distributed is essential;

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

Also learn to optimize performance

Ali's architect explained the working principle of virtual machine in detail (CSDN read 100000+ articles)

In fact, so much knowledge is not only simple to master, but also needs to be coordinated. We need to be more aware of what it is and what it must be. Of course, I will share some more interviews, including the above knowledge points in my own group: 629740746 I will share with you regularly. What we need to do in the face of p7 is to grasp our knowledge more firmly

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324962266&siteId=291194637