Past Review
In the first 12 blogs in this column, we will give a general introduction to what is JVM and the format of class files. For a deep understanding of Java or other languages running on JVM, a deep understanding of the class file format is required. If you are not familiar with the format of the class file, you are advised to read the previous 12 blogs or refer to other materials before reading the articles in this blog, familiar with the format of class files.
In this blog, we have mentioned that JVM is a special process. All the java programs we run in one JVM process, the role of this process is to load the class file and execute the code in the class file. Of course, there is still a long way to go from loading a class file to preparing for execution. later articles will detail this process. Since the virtual machine runs our program as a virtual computer, there must be a place to store our code (class files) during execution, there will always be many objects that must be stored somewhere. During execution, some execution statuses need to be saved, such as the method to be executed. After the current method is executed, the method to return and other information. Therefore, there must be a place to maintain the execution status. In the above description, the "place" refers to the memory area. After the program runs, it is a dynamic process. It is necessary to divide the memory area reasonably to store various data. Therefore, in this article, we will detail the JVM runtime data zone.
Overview of JVM architecture and runtime data Zone
To understand the JVM runtime data zone, you must first understand the JVM architecture, because the virtual machine architecture basically explains why there are these runtime data zones ". In this article, I have briefly mentioned the JVM architecture. Here I will explain it in detail. The JVM architecture is as follows:
It can be seen that the division of runtime data zones is related to the JVM architecture. This article mainly introduces the division of runtime data zones and does not explain the architecture in depth. To sum up, the class Loader subsystem is used to load the class file to the data zone of the Virtual Machine (the method zone should be accurate ). It can be considered that the execution engine is the execution mechanism of bytecode, and a thread can be considered as an instance of the execution engine. The following describes the runtime data zone:
JVM runtime data Zone
In terms of literal meaning, the word "Method Area" may lead to misunderstandings. Because the method area stores type information instead of methods. When writing a program, we almost always deal with classes and objects. We know that an object can be created based on a class. In general, we manipulate objects, access object attributes, and call object methods. But we need to think about the problem. What information does a virtual machine know how to create objects? Of course it depends on the type information of this object, but where is this type information? Now we know it is in the method area. Who loads the type information to the method area? From the architecture diagram above, do we know the class loader subsystem? So what information does the so-called type information contain? How is this information stored? The type information here can be generally considered as a class file we have explained earlier. The class loader subsystem will extract the type information in the class file, and store the type information in the method area. How to store a type of data in the method area is related to the specific implementation of JVM. However, no matter how it is implemented, the type information of a class always includes the following information:
Class Name
Full qualified name of the direct parent class of the current class
Is this class an interface type, a class type, or an enumeration type?
Class access modifier Information
Full qualified name of the current type of superinterface
Constant pool of Current Type
Field Information
Method Information
If you are familiar with the class file format, we can see that the information is described in the class file. We cannot see how the type information is stored, but we can generally regard the type information as a class file, which is helpful for our understanding. The following lists the structure of the class file again. Readers can compare the content in the class file to the type data. The data in this table has been described in detail in the previous blog:
In addition to the basic information, the type information also includes the following two aspects:
Reference of a ClassLoader object to a class
One to reference Class instance objects of this Class
Static variable Storage Area
As I have described the format of the class file in detail in my previous blog, we may be familiar with some of the above basic information, but are unfamiliar with these two types of information. In fact, it is also simple. Every class is loaded into the method area by a class Loader, And the type information is referenced in the class ClassLoader object, indicates the class loader to which the current class is loaded. This information also indicates the namespace of the current type.
Every time a class file is successfully loaded into the method area, JVM creates a Class object to uniquely identify this class. This Class object can be seen as the product of the Class loading process. because it describes the entire type information, and reflection in Java is also the type information, this Class object is the cornerstone of reflection, most reflection APIs are implemented based on Class objects.
Static variables also exist in the type information. In this case, the type information contains static variables of the class in a special region. Unlike instance variables that exist in objects, static variables exist in type data and each type has only one copy, which is also called class variables.
The method area is a relatively fixed memory area, because it stores type information, and after the type information is loaded into the method area, in addition to necessary connections and initialization, generally, there will be no major changes. In general cases, the JVM will not uninstall the type information, so the method area can also be called the static zone of JVM. A type of life cycle is generally the life cycle of the entire program. This is also the reason why you need to use static variables with caution, because static variables are stored in the method area with the type information and have a long life cycle. improper use may easily cause memory leakage. Only one method zone exists in a JVM instance, and all types of data in the method zone are shared by all threads.
The heap method area stores type data, while the heap is the object generated during running. Different from C ++, Java can only store objects in the heap, rather than allocating objects on the stack. All runtime objects are stored in the heap, including arrays. We know that in Java, arrays are also objects. One JVM instance has only one heap, and all threads share the data (objects) in the heap ).
Java Virtual Machine supports several commands for creating objects, such as new and anewarray. The execution result of these commands is to allocate memory in the heap and create objects. However, the instruction set of the Java Virtual Machine does not contain any commands to release the memory, so we cannot manually release the memory. All created objects will be automatically reclaimed by a module called the Garbage Collector (GC). The Garbage Collector has different implementation methods. They determine whether the object has expired in a specific way, the object is recycled in a specific way. The topic about garbage collection is not the focus of this article. As long as we know that all created objects exist in the heap, And the Garbage Collector automatically recycles expired objects, the JVM heap is the "key management area" of the garbage collector ".
The Java stack is the execution area of a thread. It stores the call status of methods in a thread. You can also say that the running status of a Java thread is saved by a Java stack. In this stack, each method corresponds to a stack frame. Note the two concepts of stack frame and stack. Stack refers to the execution stack of the entire thread. Stack frames are a unit in the stack. Each method corresponds to a stack frame. JVM performs two operations on the Java stack: Stack pressure and stack exit. These two operations are all in the frame (stack frame) unit during execution. When a new method is called, it is pushed into a stack frame. When a method call is completed, the stack frame of this method is displayed and returned to the stack frame of the caller.
For example, if method a calls Method B, and method c is called in method B. In this process, the method call and the returned loading status are as follows (the two dotted lines in the figure represent the Java stack, and each square represents the stack frame of a specific method)
All data on the Java stack is thread-proprietary. That is to say, each thread has its own Java stack and does not access data in other Java stacks.
The PC register pc register is used to store the address of an instruction. This instruction is the next instruction to be executed by the virtual machine. The pc register is associated with the thread. Each thread has a PC register.
We know that Java can communicate with C/C ++ on the local method stack. If the code executed by the current thread is local code written in C/C ++, these methods will be executed in the local method stack rather than in the Java stack, only Java methods are executed in the Java stack.