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

How to make a div height adaptive to the browser height

This old question has troubled countless front-end...

JavaScript implements displaying a drop-down box when the mouse passes over it

This article shares the specific code of JavaScri...

Pure HTML and CSS to achieve JD carousel effect

The JD carousel was implemented using pure HTML a...

Detailed explanation of the API in Vue.js that is easy to overlook

Table of contents nextTick v-model syntax sugar ....

Detailed explanation of the use of Vue mixin

Table of contents Use of Vue mixin Data access in...

Analysis of the process of implementing Nginx+Tomcat cluster under Windwos

Introduction: Nginx (pronounced the same as engin...

MySQL detailed single table add, delete, modify and query CRUD statements

MySQL add, delete, modify and query statements 1....

Tutorial on installing Pycharm and Ipython on Ubuntu 16.04/18.04

Under Ubuntu 18.04 1. sudo apt install python ins...

javascript to switch by clicking on the picture

Clicking to switch pictures is very common in lif...

Comparison of various ways to measure the performance of JavaScript functions

Table of contents Overview Performance.now Consol...

JS ES6 asynchronous solution

Table of contents Initially using the callback fu...

Summary of MySQL's commonly used concatenation statements

Preface: In MySQL, the CONCAT() function is used ...

How to implement web stress testing through Apache Bench

1. Introduction to Apache Bench ApacheBench is a ...