This is the 19th day of my participation in the August Wenwen Challenge.More challenges in August

We’ll start by looking at what the JVM is, what it has, and what it can do.

What is, what there is and what it can do is a basic learning idea or learning method for us to learn new technology, or to know a new thing.

For example, when we get something new, we first think about what it is, what parts it is made of, and what it can do, so as to judge whether it is useful or useless to us, or whether we need to use it. If we’re sure we’re going to use it, well, let’s go ahead and figure out how it works. How do you do that? Or how do we use it?

So that’s what it is, what it has, what it can do, and how to do it. These are some basic learning methods and ideas for us to learn a new technology or to know new things.

Let’s also take a look at how Java implements platform independence.

Summary of the JVM

The JVM, which stands for Java Virtual Machine (JVM), is a specification for computing devices. It recognizes files with the.class suffix and can parse its instructions, eventually calling functions on the operating system to do what we want. It is a fictional computer that is implemented by simulating various computer functions on an actual computer. The so-called virtual machine, it refers to the software simulation, with complete hardware system functions, and run in a completely isolated environment, such a computer system. The point is one software simulation, the other one it’s a computer system. That is to say, we think virtual machine itself can be regarded as a computer system, but it is simulated by software, it is not a real physical existence of such a computer system, so it is called virtual machine.

It features complete hardware system functions and runs in a completely isolated environment. So a computer system like this, it can run a lot of programs. Of course we are Java virtual machine, of course face running is our Java application.

The JVM is an instruction machine that simulates Java bytecode through software. To show you the instruction set, it is the CPU that executes the instruction set on the real physical machine. It emulates this instruction set through software in the JVM, the environment in which Java programs run.

All of these Java applications that we write end up running on the JVM. That is, the JVM provides a running environment for our Java programs.

How does the Java code we write actually work

Let’s take a look at the graph below.

Java Compilation environment

On the left side of this picture, it’s pretty obvious that this is our development process. First we are to write the Java source code, the.java file, and then through the Java compiler. For example, a command like javac, or use the ide tool to compile it into this Java bytecode, which is a.class file. The whole process is a development process.

When we compile it as a.class file, we are saying bytecode file. In the run-time environment, that’s our virtual machine. The first thing we do is use a ClassLoader, a ClassLoader, to pass our bytecode locally or over the network. Of course, there are not many network methods now. For example, there was a technology called applets in Java, which is rarely used now. In short, load our bytecode file into the virtual machine through the inner loader.

While loading, it must do some checksum authentication on the bytecode file. For example, verify that the bytecode file conforms to the virtual machine specification, is formatted correctly, and so on.

During this loading process, it also loads some Java panties, that is, some basic necessary support provided by the virtual machine, such as basic data types, basic if else, for loops, and so on, and loads some related processing, including some basic Java safety processing. And some hardware processing and so on. This means that the virtual machine has to provide these functions, and it will also load these panties through the class loader at this point. So when all of this stuff is loaded into the virtual machine, the virtual machine will hand it over to the Java interpreter, and the Java interpreter will interpret and execute the bytecode. The whole process is run-time.

Of course, the runtime is much more complicated than that. When we hand in.class to run, the runtime environment must first do some basic work, such as memory allocation, and the allocated memory is later used to execute the bytecode, which involves the bytecode execution engine.

During this run, garbage is generated in this memory, which is garbage collected. If there is going to be a lot of concurrent code, then there must be some efficient concurrency, etc.

Of course, there are a series of security processes during the runtime, these are all things to do at runtime, and this is our Java virtual machine, which provides an environment for our Java Class files to run, from loading to explaining the execution of the whole process.

The application needs to interact with the hardware or operating system, such as through the JIT of our virtual machine, by the virtual machine to interact with the operating system, the operating system to interact with the hardware.

Through the entire process, from writing code to the last to run such a process, basically can see the virtual machine in it, it’s position and its knowledge of some of the major, as we go through this formation has a basic understanding of the virtual machine, and for its knowledge system to form a knowledge outline.

First, Java bytecode files are required to follow the JVM specification. There will certainly be some detailed definition of the entire bytecode file. And then we load it in. Speaking of which, we definitely have to have a ClassLoader, a ClassLoader, to load it into the JVM.

So once it’s loaded in, and we’re not going to talk about this underwear, but it’s going to start actually executing, it’s going to do memory allocation during runtime. And then when this allocation is done, I’m going to explain the set of instructions to execute this code, and we’re going to use the execution engine of the bytecode. So during the execution, some garbage generated in memory, we call garbage collection, this process involves some concurrent processing, then we naturally need efficient concurrent processing and so on.

Basically is a virtual machine inside some of the most important parts, this is the need for everyone behind a bit of detail to learn, that here we do not say more.

The main features of the JVM

Let’s take a look at the main features of the JVM.

The first is to use the ClassLoader to find and load class files. How the ClassLoader finds, how it loads, and so on. We’ll talk about that later when we learn ClassLoader. Of course things like classLoaders and customizations. Without further discussion, let’s just say that the first thing the JVM does is find and load class files using this ClassLoader, so load the class files first.

The second interprets the bytecode as instructions and executes on the execution engine of the bytecode just mentioned to provide the environment in which the class files run.

The third is to do runtime memory allocation, as well as garbage collection.

The fourth is to provide a platform to interact with the hardware, through which we can also easily understand, that is, we write Java programs and hardware independent. For example, when we want to interact with hardware, we actually want the program to interact with the virtual machine, and then the virtual machine to interact with each hardware such a process.

Virtual machines are Java platform-independent guarantees

So let’s look at virtual machines as Java platform-independent guarantees. And this is probably one of the most important features of Java that you know when you start learning Java, or the feature called Java is platform-independent.

So how exactly does it work? Take a look at the picture below. The core of the picture is the virtual machine.

We see above, first Java original program this need not much, is our own.java file, through javac compiled after the formation of.class file.

These two processes are actually Java development processes. Once we have the.class file, we load it into the virtual machine and actually run it inside the virtual machine. Let’s say our class doesn’t run, right? That’s actually going to run into the virtual machine.

The virtual machine, like our program, blocks out platform-specific things. Like Linux, Windows, MacOS. Some of the things that are relevant to each platform feature are left out of our application, which means that our application is platform-independent. These platform-specific features have been blocked by virtual machines.

Think about this for a moment, when our Java virtual machine is installed on a different platform. For example, when we install Linux, Windows, MacOS and other operating systems, we install different versions.

In fact, the virtual machine installation program is platform-dependent. So the platform-independent part is that we develop Java programs that are platform-independent. So when we write programs, we don’t write a set of programs for Linux, Windows, and MacOS, but we write a set of Java source programs for virtual machines, and we don’t care which platform the virtual machine is on. So we say Java is platform agnostic.

Well, actually some of you might be thinking about this in this place. In this sense, our Java programs are not really platform-independent, but platform-dependent. But we only have one platform, the Java Virtual machine, which means that our Java programs are related to the Java Virtual machine platform.

HellWorld case

Finally, let’s take a quick look at the execution of a Java program and how it actually works.

The Java program here is in text format. For example, helloWorld.java follows the Java language specification. In it, we call modules such as System.out, which are the libraries provided in the JRE.

public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); }}Copy the code

When compiled using the JDK’s tool javac, the bytecode for HelloWorld is generated.

We’ve been talking about Java bytecode being the bridge between the JVM and Java programs, so let’s use Javap to get a glimpse of what bytecode looks like.

0 getstatic #2 <java/lang/System.out>


3 ldc #3 <Hello World>


5 invokevirtual #4 <java/io/PrintStream.println>


8 return
Copy the code

Java virtual machines use a stack-based architecture, and their instructions are composed of opcodes and operands. These bytecode instructions are called opcode. Getstatic, LDC, Invokevirtual, return, etc., are opcode, which is easy to understand.

Let’s continue with hexdump and look at the binary contents of bytecode. The binary corresponding to the above bytecode is the following numbers (you can search for them).

b2 00 02 12 03 b6 00 04 b1
Copy the code

And we can see how they correspond.

0xb2 getStatic Gets the value of a static field 0x12 Constant values in the LDC constant pool are pushed 0xB6 Invokevirtual runtime method binding calls the method 0xb1 Return void function returnsCopy the code

Opcode has a length of one byte (0 to 255), meaning that the number of opcodes in the instruction set cannot operate 256. And immediately after opcode is the operand. For example b2 00 02 represents getstatic #2 < Java /lang/ system.out >.

The JVM performs program execution by parsing these Opcodes and operands. When we run a.class file using a Java command, we actually start a JVM process.

The JVM then translates the bytecode, which can be done in two ways. A common one is interpreted execution, translating opCode + operands into machine code; Another method of execution is JIT, also known as just-in-time compilation, which compiles bytecode into machine code under certain conditions before execution.

These.class files are loaded and stored in metaspace, waiting to be called, and there is a class loader concept.

And the JVM program running, are completed on the stack, which is similar to the execution of other ordinary programs, also divided into heap and stack. For example, if we’re running main now, we’ll assign it a stack frame. When exiting the method body, the corresponding stack frame pops up. Most bytecode instructions, you’ll notice, are just continuous manipulation of stack frames.

Other chunks of data are stored in the heap. Java is more nuanced in memory partitioning, concepts that we’ll discuss in more detail in the next class.

Finally, look at the diagram below, where the JVM is the main point of the course.

 

summary

Now that you have a basic understanding of the Java virtual machine, let’s take a look at this part of the course summary.

Understanding the JVM: The focus is on understanding the entire process from Java source code to execution. The initial understanding of the JVM is divided into several parts to build up the basic knowledge of the JVM.