Here with some other front knowledge, main is to want to start from Java, from the source to comb again the whole Java underlying operating mechanism, in the middle will add some extra has nothing to do with the title of the lead, lead to the master the length of the memory model to the proportion, it is not so absolute, can only ask friends knew more about it. Have what wrong to ask much to instruct!

Before we talk about the JVM memory model, let’s talk about the age-old question of why Java can “compile once, run everywhere.” The most straightforward answer to this question is that Java has a JVM. Before I explain the answer, I’d like to review the process by which a language is compiled:

JVM memory Model

Why Java can “compile once, run everywhere”

Before we talk about the JVM memory model, let’s talk about the age-old question of why Java can “compile once, run everywhere.” The most straightforward answer to this question is that Java has a JVM. Before I explain the answer, I’d like to review the process by which a language is compiled:

In general, the process of compiling a programming language is basically compile-concatenation-execute. In this case, compiling is taking the source code that we write, translating it according to the semantic syntax, and forming object code, or assembly code. Then the assembler program is translated into machine language (can be understood as running directly on the hardware of the 01 language); Then, the connection is to connect the object code to the function library, and merge the library code used by the source program with the object code to form the final executable binary machine code (program).

The whole process of compiling and running is based on the premise that at the assembly level, the instruction code is strongly associated with the architecture of the processor, or in other words, with the hardware. It can be roughly interpreted as that a hardware machine only knows one kind of assembly, and a machine only knows one kind of machine code. Under this basis, it would be easy to find a problem, a programming language compiled form machine code can run X, connection, can run under the condition of the hardware environment 1, when the machine code 2 X to the hardware environment, it won’t be able to run, or run results, it is not the result of the hardware environment 1, so, the same program, in PC, We might need to recompile and package the program to run on the current hardware environment. This is a disaster in engineering applications.

Now to return to the answer to the opening question, the reason Why Java is “compile once, run everywhere” is because of the JVM. For the sake of understanding, let’s think of it this way: The JVM is a complete intermediate environment that provides a complete set of environments for compiling and running Java bytecode. In other words, it is like a small isolated space. My Java program is compiled once and can be ported to any hardware environment as long as it runs in the JVM. The nature of “run everywhere” is that it relies on the JVM everywhere. It’s a parasite that runs in the JVM, which is why you have to install the JDK in order to run the environment.

The nature and location of the JVM

Usually the basic work is contact with Java libraries and applications and Java core class libraries, know how to use it, but in the final analysis, the code is compiled into class files by the Java virtual machine load execution, the results or phenomenon can be explained through the Java virtual machine operation mechanism. Some of the same code will produce different results depending on the virtual machine implementation.

  • And then we will introduce the JVM, first we need to clear a concept, the JVM it is not a particular product, also is not a finished product software, more precisely the JVM specification is a kind of theory, the specific implementation of the JVM or software, or is the combination of software and hardware, the JVM can be done by different vendors into different products. Due to the different manufacturers will inevitably lead to the JVM in the implementation of some different, like the famous Domestic TaobaoVM;

  • In the structure of the Java platform, you can see that the Java Virtual Machine (JVM) is at the core, the key to programs that are independent of the underlying operating system and hardware. Below it is the migration interface, which consists of two parts: the adapter and the Java operating system, where the platform-dependent part is called the adapter; JVMS are implemented on specific platforms and operating systems through porting interfaces; On top of the JVM are Java’s basic and extended class libraries and their apis, Applications and applets written using Java API can run on any Java platform without considering the underlying platform, because the Java Virtual Machine (JVM) has realized the separation of the program and the operating system, so as to realize the platform independence of Java.

The JVM has an explicit task during its lifetime to load the bytecode files. Once the bytecode enters the virtual machine, it is either interpreted and executed by the interpreter, or optionally converted into machine code by the real-time code generator, i.e., the Java program is executed. So when a Java program is started, an instance of the JVM is generated; When the program ends, the instance disappears.

Overview of the JVM memory model

Blogger you foreplay really much, you are not a duck……”

“Ah… This is… More foreplay, more enjoyment…”

Er… In front of the foreplay is indeed some more, but mainly in order to better contact with the content behind, otherwise directly on the five memory parts, say what thread private, public, personal feeling very uncomfortable.

All right, without further ado, let’s serve the main course

In general, the JVM divides the memory managed by Java processes into several different data regions. These areas have their own purpose, creation/destruction time. The first half (runtime area) is actually the MEMORY allocation of the JVM. It divides the memory space obtained from the operating system into methods area, heap, virtual machine stack, local method stack, and program counter. The second half is the connection — the run-time, where the JVM processes the Java language into machine code appropriate for the current machine, then connects to the local library and runs.

Thread private area

Thread-private data areas have the same life cycle as threads and are created/destroyed depending on the start/end of user threads (in Hotspot VM, each thread is directly mapped to the operating system’s native thread, so this part of the memory area lives/dies with the local thread).

Program counter

A small memory space that acts as an indicator of the line number of the bytecode being executed by the current thread (similar to a PC in the traditional CPU model). The PC incretes after each instruction and maintains the address of the next instruction to be executed. In the JVM model, the bytecode interpreter selects the next byte code instruction to execute by changing the PC value. Basic functions such as branch, loop, jump, exception handling, thread recovery and so on are all dependent on the PC (only for Java methods, Native methods this counter value is undefined). Instead of scheduling on a per-process basis in the OS, concurrency in the JVM is achieved by thread switching and allocating time slices of execution. At any given time, a processor core is executing instructions from only one thread. Therefore, in order to return to the correct execution location after a thread switch, each thread needs a separate program counter. This type of memory is called “thread-private” memory.


Bytecode compiled by JAVA code is interpreted and executed by a “bytecode interpreter” before it is compiled by a JIT (real-time compiler). The simple way it works is that the interpreter reads the bytecode loaded into memory and reads the bytecode instructions in sequence. After reading an instruction, the instruction is “translated” into fixed operations, and branches, loops, jumps and other processes are carried out according to these operations.

From the above description, the question may arise as to whether program counters are redundant. Because execution along the instruction sequence, even in a branch jump, jump to the specified instruction to continue the execution of the sequence is fully guaranteed to the program execution order. There is nothing wrong with this question, assuming that the program will always have a single thread, that is, no program counter is required. But the program is actually executed by multiple threads working together. // Welcome to join the Java development exchange jun sample: 756584822

First, let’s figure out how the JVM implements multithreading. Multithreading in the JVM is achieved through the ALGORITHM of CPU time slicing (that is, threads in turn switch and allocate processor execution time). That is, one thread may be suspended during execution because the time slice is exhausted, while another thread gets the time slice and starts executing. When a suspended thread retrives the time slice, it must know where it was last executed in order to continue from where it was suspended. In the JVM, a program counter keeps track of where a thread’s bytecode was executed. Therefore, the program counter is thread isolated, that is, each thread works with its own independent counter.

Features of program counters

1. Thread isolation, each thread has its own independent counter when working.

2. When a Java method is executed, the program counter has a value and records the address of the bytecode instruction being executed (see the previous section). 3. When executing a native method, the program counter is null (Undefined). Since native methods are directly called by Java to the native C/C++ library through JNI, it can be approximated that native methods are equivalent to an interface exposed to Java by C/C++, and Java can call C/C++ methods by calling this interface. This method is implemented in C/C++ rather than Java. No bytecode is naturally generated, and memory allocation during C/C++ execution is determined by its own language, not by the JVM.

4. The program counter occupies very little memory and can be ignored when performing JVM memory calculation. >5. Program counters are the only area where the Java Virtual Machine specification does not specify any OutofMemoryErrors.

The virtual machine stack

The virtual machine stack here is mainly for Java method execution, we all know that the method in the programming is using the stack data structure; When each method is executed, a Stack Frame is created to store information about local variables, operand stacks, dynamic links, method exits, and so on. Each method that is called to return corresponds to a stack frame that is pushed from the stack to the stack of the virtual machine. (The VM provides -xss to specify the maximum stack space for the thread, and this parameter directly determines the maximum depth of the function call.)

In particular, the local variable table is the variable inside the method we define. Its basic scope includes the basic data types (e.g., Boolean, int, double, etc.), and the object reference (e.g., Boolean, int, double, etc.). Is not equivalent to the object itself, but may be a pointer to the start address of the object, a handle to the object, or some other location related to the object), which is commonly referred to as’ stack ‘within’ stack ‘.

  • The Java Virtual Machine uses local variable tables to complete parameter passing in method calls. The length of the local variable table is determined at compile time and stored in the binary representation of the class and interface. A local variable can hold a type ofBoolean, byte, char, short, float, Reference, and returnAddressTwo local variables can hold data of types long and double.

 

  • The Java virtual machine provides bytecode instructions to copy constant or variable values from a local variable table or field of an object instance into the operand stack. It also provides instructions for fetching data from the operand stack, manipulating data, and repushing the results of the operation. During a method call, the operand stack is also used to prepare the parameters of the calling method and to receive the results returned by the method.

 

  • Each stack frame contains a dynamic link to the runtime constant area that references the supported method. In Class files, method calls and access to member variables are represented by symbolic references. Dynamic linking is used to convert symbolic references into direct references to the actual method or to the correct offset of the memory location where the access variable runs.

In general, the Java virtual machine stack is used to store local variables and procedure results.

The following exceptions may occur in the Java virtual machine stack: If the Java virtual machine stack is implemented as a fixed size memory, the Java virtual machine will throw a StackOverflowError exception when the requested stack capacity exceeds the maximum allowed capacity of the Java virtual machine stack.

The Java virtual machine will throw an OutOfMemoryError if the Java virtual machine stack is implemented to dynamically expand the memory size, if the expansion has been attempted, but there is not enough memory available to complete the expansion, or if there is not enough memory to create the corresponding virtual machine stack when a new thread is created.

Symbolic reference

A symbolic reference is a set of symbols that describe the object being referenced. A symbol can be any literal, as long as it is used to locate the object unambiguously. For example, it appears in Class files as constants of types CONSTANT_Class_info, CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and so on. Symbolic references are independent of the memory layout of the virtual machine, and the target of the reference is not necessarily loaded into memory. In Java, a Java class is compiled into a class file. At compile time, the Java class does not know the actual address of the referenced class, so only symbolic references can be used instead.

For example, the org.simple.People class references the org.simple.Language class. At compile time the People class does not know the actual memory address of the Language class, so it can only use the symbol org.simple.Language (suppose this, Of course, this is actually represented by a constant like CONSTANT_Class_info) to represent the address of the Language class. The memory layout of the various virtual machine implementations may differ, but they will all accept the same symbolic references because the literal form of symbolic references is clearly defined in the Java virtual Machine specification’s Class file format.

Direct quote:

A direct reference can be

  • (1) A pointer directly to a target (for example, a direct reference to a “type” [Class object], a Class variable, or a Class method might be a pointer to a method area)

  • (2) Relative offsets (for example, direct references to instance variables and instance methods are offsets)

  • (3) a handle that indirectly locates the target

Direct references are related to the layout of the virtual machine. The same symbolic reference will not translate the same direct reference across different virtual machine instances. If there is a direct reference, the target of the reference must already be loaded into memory.

Local method stack

The local method stack is the same as the virtual machine stack, except that the virtual machine stack is used to parse and run Java methods for the virtual machine, while the local method stack is used to invoke Native method services for the virtual machine. 756584822 is an interface for Java to call non-Java code. A Native method is a Java method whose implementation is implemented in a non-Java language.

Thread shared area

The life cycle of this region is the same as that of the VIRTUAL machine, that is, the public memory region inside the VIRTUAL machine. It is created and destroyed when the virtual machine is started or stopped

The heap area

This space is the largest chunk of memory managed by the Java virtual machine, and is shared by all threads. The Java heap is created when the virtual machine is started and is mainly used to allocate memory for class instance objects and arrays. This area can be discontinuous in the physical memory space, as long as the logic is continuous, like our disk space, in the implementation, can achieve a fixed size, also can be extended, if is extensible, by (-xmx and – Xms control), if there is no memory in the team completed instance allocations, An OutOfMemoryError is thrown when the heap is no longer growing.

The Java heap is the main area managed by the garbage collector and is often referred to as the “GC” heap. In the current implementation, the heap is divided into two different areas: Young and Old; This is the “generational collection algorithm” adopted by the JVM. Simply put, it is the implementation of different strategies for storing and recycling Java objects with different characteristics. Naturally, the allocation mechanism and recycling algorithm are different. The Young generation is divided into three regions: Eden, From Survivor, and To Survivor. // Welcome to join the Java development exchange jun sample: 756584822

Methods area

The method area, like the Java heap, is an area of memory shared by each thread. It is used to store information about classes that have been loaded by the virtual machine, constants, static variables, and special methods for class, instance, and interface initialization. The virtual machine specification describes the method area as a logical part of the heap, but it has a nickname “non-heap” to distinguish it from the Java heap.

Direct memory

Direct memory is not part of the JVM runtime data area, but is frequently used: NIO, introduced in JDK 1.4, provides Channel – and buffer-based I/O. It uses Native libraries to allocate memory directly out of the heap, and then uses DirectByteBuffer objects as references to this memory (see: Java I/O extensions), which avoids copying data back and forth between the Java and Native heaps, thus significantly improving performance in some scenarios. Obviously, the allocation of native direct memory is not limited by the Java heap size (that is, it is not subject to -xMS, -xmx, and so on), but since it is memory, it is certainly still limited by the total native memory size and processor addressing space, so you can also get OutOfMemoryError exceptions when scaling dynamically.

Understanding memory models

Here we introduce a simple example program to understand the Jvm’s memory from a code perspective

A person class

public class Persion {
    private String name;
    public static String aninmal = "dog" 
    
     public Persion(String name){
        this.name = name
    }

    public String getName() {
        return name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
// Welcome to join the Java development exchange jun sample: 756584822
   
}
Copy the code

An App class

public class App 
{
    public static void main( String[] args )
    {
        Persion persion1 = new Persion("Zhang"); 
        Persion persion2 = new Persion("Bill");
        persoion1.setName("Fifty"); }}Copy the code

The program starts to run. The system starts a Java virtual machine process. The Java virtual machine locates the bytecode of the main() method of the App class in the method area and starts to execute its instructions. Create Persion1 and Persion2, respectively.

1. The program starts with the main method, and since we mention methods, we know that it starts on the stack first. In a JAVA virtual Machine process, each thread has a stack of method calls that track a series of method calls as the thread runs. Each element of the stack is called a stack frame. Every time a thread calls a method, a new frame is pushed into the method stack. Frames are used to store method parameters, local variables, and temporary data during the operation. The main thread that executes the main method will claim an area in the stack. According to the source code, it recognizes persion1 and persion2 as variables, respectively, and qualitatively defines them as local variables within the method, so it is added to the JAVA method call stack on the main thread that executes the main() method.

The next step is to assign “=”. The Java virtual machine accepts the command, finds an object instance on the right, and goes straight to the method area, trying to find the type information of the Persion class. On the first run, no Persion information is found. In this case, the Java VM loads the Persion class and stores the Persion type information in the method area according to the preset rules.

The Persion class animal is filled with the value “dog” and is stored in the method area. The Java virtual machine (JVM) allocates two memory areas to the heap according to the new instructions in our code. Persion instance 1 and Persion instance 2, each with its own separate memory space, hold a reference to the type information of the Persion class in the method area. Persion instance 1, Persopn instance 2, Persion instance 1, persopn instance 2, Persion instance 1, persopn instance 2, Persion instance 1, persopn instance 2, Persion instance 1, persopn instance 2, Persion instance 1, persopn instance 2 We can also see that persion instance 1 and Persion instance 2 share the animal variable, which means that each persion object will change the animal variable whenever it is used.

The two member variables persion1 and persion2 in the main method have so far been associated with objects in the heap, respectively. When the Java VIRTUAL machine executes persion1.setname (), the Java virtual machine will locate the instance (Persion 1) in the heap based on the persion1 variable in the stack of the main method. Then, based on the reference (or pointer) to the class information held by the instance, locate the Persion class information in the method area, get the setName(String name) method from the Persion class information, then push the stack into a new frame, copy the parameter (String name) in it, and then follow the instruction, Change the Name in the Persion instance 1 space in the heap to “King five” and then end.

Reference documentation

There are a lot of dry products, including mysql, Netty, Spring, thread, Spring Cloud, JVM, source code, algorithm and so on. There are also detailed learning planning map, interview question sorting and so on. Need to get these content friends scan below the QR code to get free: 、