JVM: JVM memory partitioning

Overview
Readers who have studied C or C++ at work or at work will surely find that the memory management mechanisms of these two languages ​​are different from those of Java. When programming in C or C++, programmers need to manually manage and maintain memory, that is to say, they need to manually clear those unnecessary objects, otherwise there will be memory leaks and memory overflow problems.

If you use the Java language to develop, you will find that in most cases you don't need to care about the recycling of useless objects and memory management, because the JVM virtual machine has already done it for us. Understanding the various areas of JVM memory will help us gain insight into its management mechanism, avoid memory-related problems and solve them efficiently.

Leading to the problem
We use many different types of data when programming in Java, such as temporary variables, static variables, objects, methods, classes, and so on. So is there any difference in how they are stored? Or where do they exist?

Runtime Data Areas
During the execution of Java programs, the Java virtual machine divides the memory it manages into several different data areas, each with its own purpose.
insert image description here

Among them, the heap and method area are shared between threads, while the stack and program counter are thread-private.

The program counter
is thread-private and can be seen as an indicator of the line number of the bytecode executed by the current thread. When the bytecode interpreter works, it selects the next bytecode instruction to be executed by changing the value of this counter. Basic functions such as branching, looping, exception handling, and thread recovery all need to rely on this counter to complete.
This is the only area that does not specify any OOM exceptions.
Virtual machine stack
The virtual machine stack is also thread-private and has the same life cycle as the thread. The stack stores local variables of methods, references to objects, and so on.
In this area, two exceptions are specified. When the stack depth requested by the thread is greater than the depth allowed by the virtual machine, a StackOverflowError exception will be thrown. When the dynamic expansion of the virtual machine stack fails to apply for enough memory, an OOM exception will be thrown.
The native method stack
has the same function as the virtual machine stack, except that it serves the Native method. The HotSpot virtual machine directly combines the virtual machine stack and the local method stack into one.
Heap
The heap is the largest piece of memory managed by the Java virtual machine. It is a memory area shared by all threads and created when the virtual machine starts. The only function of this area is to store object instances, that is, objects from NEW. This area is also the main area of ​​action of the Java garbage collector.
When the size of the heap can no longer be expanded, an OOM exception will be thrown.
It can be said that the only function of this memory area is to store object instances, and almost all object instances and arrays allocate memory here.
The Java heap is the main area managed by garbage collection and is therefore also known as the GC heap. Garbage collection uses a generational garbage collection algorithm, so the Java heap can also be subdivided: the new generation (more detailed into Eden, From Survivor, To Survivor) and the old generation. The purpose of further division is to reclaim memory better, or to allocate memory faster.
insert image description here

Method area
The method area is also a memory area shared by threads, which is used to store class information, constants, static variables, etc. that have been loaded by the virtual machine. When the method area cannot meet the memory allocation requirements, an OOM exception will be thrown. This area is also known as the permanent generation.
Supplement
Although there is no runtime constant pool and direct memory in the above figure, these two parts are also frequently touched by us during development. So add it to everyone.

Runtime constant pool The runtime
constant pool is a part of the method area. In addition to the class version, field, method, interface and other description information in the Class file, there is also a piece of information called the constant pool, which is used to store various types generated during compilation. Literal and symbolic references, this part will be stored in the runtime constant pool in the method area after the class is loaded. An OOM exception is also thrown.
Direct memory
Direct memory is not part of the data area when the virtual machine is running, nor is it the memory area defined in the Java virtual machine specification, but it is a piece of memory that will be used directly during NIO operations. Although it is not limited by virtual machine parameters, it is still It will be limited by the total memory of the machine, and an OOM exception will be thrown.
Here is a concept that I hope everyone can clear up. The permanent representative method area when using the generational garbage collection algorithm in the heap is not in the heap memory. The above picture puts it together to illustrate that the generational garbage collection algorithm will work on these areas.

Changes in JDK 1.8
For the method area, it is shared by threads and is mainly used to store class information, constant pool, method data, method code, etc. We call this area the permanent generation. It is also the area where JVM garbage collection comes into play.

Most programmers should have seen the java.lang.OutOfMemoryError: PermGen space exception, where the PermGen space actually refers to the method area. Since the method area mainly stores the relevant information of the class, it is more likely to overflow the memory of the permanent generation in the case of dynamically generated classes. The typical scenario is that there are many JSP pages, and the memory overflow of the permanent generation is prone to occur.

In JDK 1.8, the HotSpot virtual machine no longer has the PermGen space method area, and it is replaced by something called Metaspace (metaspace).
insert image description here

The biggest difference between the metaspace and the method area is that the metaspace is no longer in the virtual machine, but uses local memory. By default, the size of the metaspace is limited only by local memory.

The constant area was originally in the method area, but now the method area is removed, so the constant pool is put down in the heap.

The benefits of doing this are:

The benefits of this change:

String constants are stored in the method area, which is prone to performance problems and memory overflow.
It is difficult to determine the size of class and method information, so it is difficult to specify the size of the method area. If it is too small, the method area will overflow, and if it is too large, it will easily lead to insufficient space in the heap.
Garbage collection in the method area will bring unnecessary complexity, and the recovery efficiency is low (garbage collection will be introduced in the next chapter).
Virtual machine object demystification
Object creation process, it is best to remember, and to know what each step is doing.
insert image description here

Class loading check: When the virtual machine encounters a new instruction, it first checks whether the parameter of this instruction can locate the symbol of this class in the constant pool, checks whether the class represented by the symbol reference of this class has been loaded, parsed, initialized. If not, the corresponding class loading process must be performed first. Simply put, it depends on whether the class of the object has been loaded.
Allocating memory: After the class loading check passes, the virtual machine will allocate memory for the new object. The memory size required by the object can be determined after the class is loaded, and the task of allocating space for the object is equivalent to dividing a piece of memory of a certain size from the Java heap.
There are two allocation methods: pointer collision and free list. The choice of which method is determined by whether the Java heap is regular, and whether the Java heap is regular is determined by whether the garbage collector has a compression function (the copy algorithm and the mark-cleaning algorithm are regular, and the mark-clearing algorithm is not regular).
insert image description here

Memory allocation concurrency issues

CAS fails to retry, CAS is an implementation of objective lock.
TLAB: Pre-allocate a block of memory in Eden for each thread. When the JVM allocates memory to objects in the thread, it first allocates it in TLAB. If it is not enough, use CAS to allocate it.
Initialize zero value: After the memory allocation is completed, the virtual machine initializes the memory space to be allocated to zero value (excluding the object header). This step ensures that the object instance can be used directly without assigning an initial value in Java.
Set the object header: After the initialization of the zero value is completed, the virtual machine needs to perform necessary settings on the object. For example, the hash code of the object, the age information of the GC generation of the object, and the biased lock, these information are placed in the object header.
Execute the init method: After the above work is completed, from the perspective of the virtual machine, a new object has been generated. Then execute the init method to initialize the object according to the programmer's wishes.
Object composition
In the HotSpot virtual machine, the layout of objects in memory can be divided into three areas: object header, instance data, and alignment padding.

The object header contains two parts of information, the first part is used to store the runtime data of the object itself (hash code, GC generational age, lock status flag), and the other part is the type pointer, which is the pointer to its class metadata, virtual The machine uses this pointer to determine which class the object is an instance of.

Valid information about the object stored in the instance data section.

It acts as a placeholder for its filling.

The object's access anchor
handle.
direct pointer.
Supplement
String str1 = "abcd";
String str2 = new String("abcd");
System.out.println(str1==str2);//false There is a difference between
copying
the objects created by these two methods, the first The way is in the constant pool, and the second way is in the heap memory.
insert image description here

The String object created directly by using the double quotation mark declaration will be directly stored in the constant pool.

If you do not use the String object declared by the constant pool, you can use the intern method provided by String. String.intern() is a Native method. Its function is: if the constant pool already contains a string equal to the content of this String object at runtime, Then return the reference of the string in the constant pool; if not, create a string with the same content as this String in the constant pool, and return the reference of the string created in the constant pool.

String s1 = new String("Computer");
String s2 = s1.intern();
String s3 = "Computer";
System.out.println(s2);//Computer
System.out.println(s1 == s2) ;//false, because one is a String object in the heap memory and the other is a String object in the constant pool,
System.out.println(s3 == s2);//true, because both are String objects in the constant pool
Copy
String str1 = "str";
String str2 = "ing";

String str3 = "str" ​​+ "ing";//Object in the constant pool
String str4 = str1 + str2; //New object created on the heap
String str5 = "string";//Object
System in the constant pool .out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false
copy
String s1 = new String ("abc"); How many objects are created in this sentence?

First, the string "abc" is put into the constant pool, and then a new string "abc" is put into the Java heap. References on the stack point to objects on the heap.

Most of the wrapper classes of Java basic types implement the constant pool technology, namely Byte, Short, Integer, Long, Character, Boolean. The five wrapper classes except Boolean all create [-128 127] cache data by default, and new objects are still created beyond this range. Float and Double do not implement constant pool technology.

Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);// output true
Integer i11 = 333;
Integer i22 = 333;
System.out.println(i11 == i22);// Output false
Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// output false
and copy
Integer i1=40; Java will directly encapsulate the code as Integer i1=Integer when compiling. valueOf(40); to use the object in the constant pool.
Integer i1 = new Integer(40); In this case a new object will be created.
Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);//Output false

Guess you like

Origin blog.csdn.net/m0_54861649/article/details/126371631