JVM runtime data area-heap (heap memory)

Runtime data area-heap

The core concept of the heap

The description of the Java heap in the "Java Virtual Machine Specification" is: all object instances and arrays should be allocated on the heap at runtime. (The heap is the run-time data area from which memory for all class instances and arrays is allocated).

But from a practical perspective, "almost" all object instances allocate memory here. Because there are still some objects allocated on the stack, and arrays and objects may never be stored on the stack, because the stack frame saves a reference, this reference points to the location of the object or array in the heap.

  • The heap is unique to a JVM process, which means that a process corresponds to a JVM instance, but the process contains multiple threads, and they share the same heap space;
  • There is only one heap memory for a JVM instance, and the heap is the core area of ​​Java memory management;
  • The Java heap area is created when the JVM starts, and its size is determined, and it is the largest memory space managed by the JVM;
  • But the size of the heap memory can be adjusted;
  • The "Java Virtual Machine Specification" stipulates that the heap can be in a physically discontinuous memory space, but logically it should be regarded as continuous (comparable to an operating system);
  • The Java heap can be divided into thread-private buffers (Thread Local Allocation Buffer, TLAB), which means that not all information in the heap is shared by threads.

The following code explains the heap memory:

public class HeapDemo {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("start...");
        try {
    
    
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        System.out.println("end...");
    }
}

Set the heap size:

-Xms10m: minimum heap memory
-Xmx10m: maximum heap memory
Insert picture description here

The following figure shows the use of Java VisualVM to view the contents of the heap space through the GC plug-in in VisualVM.
Insert picture description here

After the method ends, the objects in the heap will not be removed immediately, they will only be removed during garbage collection, that is, when the GC is triggered, will they be collected.

Because if the objects in the heap are reclaimed immediately, the user thread will be affected.

The connection between the heap, the Java stack and the method area:
Insert picture description here
heap memory breakdown

The heap memory of Java 7 and before is logically divided into three parts: newborn area + senior care area + permanent area:

  • Young Generation Space Young/New is divided into Eden area and Survivor area;
  • Tenure generation space Old/Tenure;
  • Permanent Space Perm.

The heap memory of Java 8 and later is logically divided into three parts: Newborn area pension area + meta space:

  • Young/New in Young Generation Space is divided into Eden area and Survivor area;
  • Tenure generation space Old/Tenure;
  • Meta Space Meta.

Agreement: Newborn area -> New generation -> Younger generation, senior care area -> Older area -> Old generation, permanent area -> Permanent generation The
Insert picture description here
internal structure of the heap space, before JDK1.8, replace the permanent generation to the meta space! ! !
Insert picture description here
The heap space logically includes the Cenozoic, the Old Generation, and the Metaspace, but actually only includes the Cenozoic and the Old Generation. The Metaspace is also called the Method Area! ! !

Set heap memory size and OOM

The Java heap area is used to store Java object instances, so the size of the heap is already set when the JVM is started, and can be set by the options "-Xmx" and "-Xms".

  • "-Xms" is used to indicate the initial memory of the heap area, which is equivalent to -xx:InitialHeapSize;
  • "-Xmx" is used to indicate the maximum memory of the heap area, which is equivalent to -XX:MaxHeapSize.
  • Once the memory size in the heap area exceeds the maximum memory specified by "-xmx", an outofMemoryError exception will be thrown.
  • Usually the two parameters -Xms and -Xmx are configured with the same value, the purpose is to be able to calculate the size of the heap area without re-computing the heap area after the Java garbage collection mechanism has cleaned up the heap area, thereby improving performance.

by default:

  1. Initial memory size: physical computer memory size/64;
  2. Maximum memory size: physical computer memory size/4.

The following code test to view the heap memory size:

public class HeapSpaceInitial {
    
    
    public static void main(String[] args) {
    
    

        //返回Java虚拟机中的堆内存总量
        long initialMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024;
        //返回Java虚拟机试图使用的最大堆内存量
        long maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024;

        System.out.println("-Xms : " + initialMemory + "M");
        System.out.println("-Xmx : " + maxMemory + "M");

        //System.out.println("系统内存大小为:" + initialMemory * 64.0 / 1024 + "G");
        //System.out.println("系统内存大小为:" + maxMemory * 4.0 / 1024 + "G");

        try {
    
    
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }
}

Output result

-Xms : 246M
-Xmx : 3934M

How to view the memory allocation of heap memory:

jps  ->  jstat -gc 进程id

Insert picture description here
Insert picture description here
OutOfMemory example

Code example:

public class OOMTest {
    
    
    public static void main(String[] args) {
    
    
        ArrayList<Picture> list = new ArrayList<>();
        while(true){
    
    
            try {
    
    
                Thread.sleep(20);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            list.add(new Picture(new Random().nextInt(1024 * 1024)));
        }
    }
}

class Picture{
    
    
    private byte[] pixels;

    public Picture(int length) {
    
    
        this.pixels = new byte[length];
    }
}

Set startup parameters

-Xms500m -Xmx:500m
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.heu.heap.OOMTest.main(OOMTest.java:21)

View the specific memory usage through the VisualVM tool:

Insert picture description here
It can be seen that when the Used heap reaches 500, an OOM exception will occur.

Young and Old

Java objects stored in the JVM can be divided into two categories:

  • One type is instantaneous objects with a short life cycle. This type of object is created and died very quickly. If the life cycle is short, it can be recycled in time;
  • The life cycle of another type of object is very long, and in some extreme cases can still be consistent with the life cycle of the JVM.

If the Java heap area is further subdivided, it can be divided into young generation (YoungGen) and old generation (oldGen).

Among them, the young generation can be divided into Eden space, Survivor0 space and Survivor1 space (sometimes called from area and to area).
Insert picture description here
The following heap parameters are generally not adjusted during development:
Insert picture description here

  • Eden:From:to -> 8:1:1
  • The new generation: the old generation -> 1: 2

Configure the proportion of the young generation and the old generation in the heap structure:

  • The default -XX:NewRatio=2 means that the new generation accounts for 1, the old generation accounts for 2, and the new generation accounts for 1/3 of the entire heap;
  • You can modify -XX:NewRatio=4, which means that the new generation occupies 1, the old generation occupies 4, and the new generation occupies 1/5 of the entire heap;
  • When it is found that there are too many objects with a long life cycle in the whole project, then you can adjust the size of the old generation for tuning;
  • In the HotSpot virtual machine, the default ratio between the Eden space and the other two survivor spaces is 8:1:1. Of course, developers can adjust this space ratio through the option "-xx:SurvivorRatio". For example -xx:SurvivorRatio=8.

Almost all Java objects are new in the Eden area, and most (80%) Java objects are destroyed in the new generation. (Some large objects cannot be stored in the Eden area, they will go directly to the old generation) .

You can use the option "-Xmn" to set the maximum memory size of the new generation.
And this parameter generally uses the default value.
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_33626996/article/details/113888562