JVM 메모리 누수 시뮬레이션

16418 단어 jvm
우선 jvm의 메모리 구조에 대한 지식 약술을 알아야 한다. 무더기에 저장된 new 대상, 그리고 전역 변수 공간(metaspace)에 저장된 것은class 파일, 예를 들어class와 Method 대상, 이른바 몇 가지 방법이다.
asm 의존
<dependency>
            <groupId>asm</groupId>
            <artifactId>asm</artifactId>
            <version>3.3.1</version>
</dependency>

클래스 생성
package com.example.demo.test;
import java.util.ArrayList;
import java.util.List;

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

public class MetaSpace extends ClassLoader {

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


장면 시뮬레이션
package com.example.demo.test;

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

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

@RestController
public class TestController {

    private List<User> userList = new ArrayList<>();
    private List<Class<?>> classList = new ArrayList<Class<?>>();

    /**
     *   -Xms32M -Xmx32M
     * Exception in thread "http-nio-8080-exec-1" java.lang.OutOfMemoryError: GC overhead limit exceeded
     */
    @GetMapping("/heap")
    public void heap(){
        int i = 0;
        while (true){
            userList.add(new User(i++, UUID.randomUUID().toString()));
        }
    }

    /**
     *   -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M
     * Exception in thread "http-nio-8080-exec-1" java.lang.OutOfMemoryError: Metaspace
     */
    @GetMapping("/nonHeap")
    public void nonHeap(){
        int i = 0;
        while (true){
            classList.addAll(MetaSpace.createClasses());
        }
    }

}

좋은 웹페이지 즐겨찾기