Detailed explanation of the JVM series memory model

Detailed explanation of the JVM series memory model

1. Memory model and runtime data area

This chapter will introduce the Java Virtual Machine Memory Model. It can be understood that the JVM runtime database is a specification, and the JVM memory model is an implementation of this specification.

The Java virtual machine focuses on storing data in the heap and method area, so this chapter also focuses on describing these two aspects in detail. The heap and method area are shared memory, while the Java virtual machine stack, Native method stack, and program counter are thread-private.

2. Mind Maps and Legends

One is the non-heap area (method area), which is also generally referred to as the "permanent generation". The other is the heap area, which is divided into the young area and the old area. The young area is divided into two parts, one is the Eden area, and the other is the Survivor area (S0+S1). The S0 area can also be called the From area, and S1 can also be called the To area.

3. Objects apply for space from JVM

4. Why do we need a Survivor zone?

Why do we need a survivor area? Isn't Eden enough?

Assuming that the Survivor area is not designed, a MinorGC is performed in the Eden area, and the objects are directly sent to the Old area. In this way, the Old area will be filled up quickly. Once the Old area is full, FullGC will be performed (the Old area will perform MajorGC, usually accompanied by MinorGC). FullGC is very time-consuming, so the purpose of designing the Survivor area is to reduce the number of objects sent to the Old area. There is a transitional Survivor area.

Supplement: Minor GC: New Generation
Major GC: Old Generation
Full GC: New Generation + Old Generation
Eden:S1:S2 is 8:1:1

5. Why do we need two Survivor zones?

The purpose of requiring two Survivor areas is to avoid memory fragmentation. Why do you say that?
Assuming that only one Survivor space is designed, once the Eden space is full, Minor GC will be performed, and the surviving objects in the Eden space will be moved to the Survivor space. When the Eden space is full next time, the problem arises. Minor GC will force the Eden space objects to be moved to the Survivor space, which will cause the memory occupied by the objects to be discontinuous.

6. Examples for verification

Heap memory overflow

import lombok.Data;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class HeapController {

    List<Foo> list = new ArrayList<Foo>();
    @GetMapping(value = {"heap"})
    public String heapTest() {
        while (true) {
            list.add(new Foo());
        }
    }


    @Data
    class Foo {
        String str;
    }
}

When accessing the interface, a memory overflow occurs;

java.lang.OutOfMemoryError: Java heap space

...

You can set parameters: for example -Xms64M -Xmx512M

Method area memory overflow

Using asm, maven configuration:

<dependency>
  <groupId>asm</groupId>
  <artifactId>asm</artifactId>
  <version>3.3.1</version>
</dependency>

Write the code and add the Class information to the method area. Note that if the computer performance is not good enough, do not execute this code. It is easy to cause the computer to restart. If it consumes too much memory, you can also reduce the number of loops.

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.util.ArrayList;
import java.util.List;

public class MyMetaspace extends ClassLoader {

  public static List<Class<?>> createClasses() {
    List<Class<?>> classes = new ArrayList<Class<?>>();
    for (int i = 0; i < 10000000; ++i) {
      ClassWriter cw = new ClassWriter(0);
      cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Class" + i, null,
              "java/lang/Object", null);
      MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
              "()V", null, null);
      mw.visitVarInsn(Opcodes.ALOAD, 0);
      mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object",
              "<init>", "()V");
      mw.visitInsn(Opcodes.RETURN);
      mw.visitMaxs(1, 1);
      mw.visitEnd();
      MyMetaspace test = new MyMetaspace();
      byte[] code = cw.toByteArray();
      Class<?> exampleClass = test.defineClass("Class" + i, code, 0,
              code.length);
      classes.add(exampleClass);
    }
    return classes;
  }
}

Method area test interface:

import com.example.jvm.jvmexceptionexample.asm.MyMetaspace;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class NonHeapController {

    List<Class<?>> list = new ArrayList<Class<?>>();

    @GetMapping(value = {"/noheap"})
    public String noheap() {
        while (true) {
            list.addAll(MyMetaspace.createClasses());
        }
    }

}

java.lang.OutOfMemoryError: Metaspace

at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.5_54]

Solution: Set the size of Metaspace, such as -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=512M

Java Virtual Machine Stack

As we learned earlier, the Java virtual machine stack is stored in the form of stack frames. One method corresponds to one stack frame, which is pushed into the stack in a queue mode. Therefore, if you want to test whether the program causes problems with the Java virtual machine stack, you can test it through a recursive method:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StackController {

    public static long count = 0;

    public static void add(long i) {
        count ++ ;
        add(i);
    }

    @GetMapping(value = {"stack"})
    public void stack() {
        add(1);
    }

}

StackOverflow, stack overflow exception:

java.lang.StackOverflowError: null

at com.example.jvm.jvmexceptionexample.controller.StackController.add(StackController.java:14) ~[classes/:na]

Solution: Set -Xss256k: Set the stack size for each thread. After JDK 5, the stack size of each thread is 1M, and before that, the stack size of each thread was 256K.

The above is the detailed content of the detailed explanation of the memory model of the JVM series. For more information about the memory structure of the JVM memory model, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of the difference between Java memory model and JVM runtime data area
  • Graphical JVM memory model
  • Summary of JVM memory model knowledge points
  • An article to help you understand the JVM memory model

<<:  Tutorial on installing mysql5.7.23 on Ubuntu 18.04

>>:  Tutorial on building a zookeeper server on Windows

Recommend

The neglected special effects of META tags (page transition effects)

Using js in web design can achieve many page effec...

How to use JS WebSocket to implement simple chat

Table of contents Short Polling Long-Polling WebS...

mysql5.7 remote access settings

Setting up remote access in mysql5.7 is not like ...

Nodejs-cluster module knowledge points summary and example usage

The interviewer will sometimes ask you, tell me h...

Problems and solutions for installing Docker on Alibaba Cloud

question When installing Docker using Alibaba Clo...

Detailed explanation of MySQL redo log (redo log) and rollback log (undo logo)

Preface: The previous article described several c...

Detailed explanation of 6 ways of js inheritance

Prototype chain inheritance Prototype inheritance...

How to reset Zabbix password (one-step)

Problem Description Since we don't log in to ...

How to set the default value of a MySQL field

Table of contents Preface: 1. Default value relat...

How to implement nested if method in nginx

Nginx does not support nested if statements, nor ...

Implementation of Nginx load balancing cluster

(1) Experimental environment youxi1 192.168.5.101...

Detailed explanation of mixins in Vue.js

Mixins provide distributed reusable functionality...