JVM 시리즈 메모리 모델 상세 설명

1.메모리 모델 과 실행 시 데이터 영역
이 장 에 서 는 자바 가상 컴퓨터 메모리 모델(자바 Virtual machine menory model)을 학습 합 니 다.jvm 이 실 행 될 때 데이터 베 이 스 는 규범 이 고 JVM 메모리 모델 은 규범 을 바 꾸 는 실현 입 니 다.

자바 가상 컴퓨터 는 데 이 터 를 쌓 고 방법 구역 에 중점 을 두 기 때문에 본 장 에서 도 이 두 가지 측면 에서 비교적 상세 하 게 설명 한다.쌓 기 및 방법 구역 은 메모리 공유 이 고 자바 가상 컴퓨터 스 택,Native 방법 스 택,프로그램 계수 기 는 스 레 드 개인 입 니 다.

2.사고 지도 와 사례

하 나 는 비 퇴적 구역(방법 구역)이 고 방법 구역 도 일반적으로'영구 대'라 고 불 린 다.또 하 나 는 퇴적 구역 으로 영 구역 과 old 구역 으로 나 뉘 는데 영 구역 은 두 부분 으로 나 뉘 는데 하 나 는 에덴 구역 이 고 하 나 는 Survivor 구역(S0+S1)이 며 S10 구역 은 From 구역 이 라 고도 할 수 있 고 S1 은 To 구역 이 라 고도 할 수 있다.

3.대상 이 JVM 에 공간 신청

4.왜 Survivor 구역 이 필요 합 니까?
왜 Survivor 구역 이 필요 합 니까?에덴 만 있 으 면 안 돼 요?
만약 에 Survivor 구역 을 설계 하지 않 으 면 Eden 구역 에서 MinorGC 를 한 번 진행 하면 대상 은 Old 구역 으로 바로 보 내 집 니 다.그러면 Old 구역 은 금방 채 워 지고 Old 구역 이 꽉 차 면 FullGC(Old 구역 은 MajorGC 를 진행 하고 보통 MinorGC 를 수반 합 니 다)를 진행 합 니 다.FullGC 는 시간 이 많이 걸 리 기 때문에 Survivor 구역 을 설정 하 는 목적 은 대상 이 Old 구역 으로 보 내 지 는 것 을 줄 이 고 과도 적 인 Survivor 구역 이 있 습 니 다.
Minor GC:신세대
주요 GC:구시 대
Full GC:신세대+노년기
Eden:S1:S2 는 8:1 입 니 다.
5.왜 두 개의 Survivor 구역 이 필요 합 니까?
두 개의 Survivor 구역 이 필요 한 목적 은 메모리 파편 화 를 피하 기 위해 서 이다.왜 그 랬 어 요?
만약 에 하나의 Survivor 구역 만 설계 하면 Eden 구역 이 꽉 차 면 Minor GC 가 진행 되 고 Eden 구역 의 생존 대상 은 Survivor 구역 으로 이동 하 며 다음 Eden 구역 이 꽉 차 면 문제 가 발생 한다.MinorGC 를 진행 하면 Eden 구역 의 대상 을 Survivor 구역 에 억지로 두 면 대상 이 차지 하 는 메모리 가 연속 되 지 않 는 다.
6.예 를 들 어 검증
메모리 넘 침

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;
    }
}
인터페이스 에 접근 하여 메모리 가 넘 칩 니 다.
java.lang.OutOfMemoryError: Java heap space
...
매개 변 수 를 설정 할 수 있 습 니 다:예 를 들 어-Xms64M-Xmx512M
방법 영역 메모리 넘 침
asm,maven 설정 사용:

<dependency>
  <groupId>asm</groupId>
  <artifactId>asm</artifactId>
  <version>3.3.1</version>
</dependency>
코드 를 작성 하고 방법 구역 에 Class 정 보 를 추가 합 니 다.컴퓨터 의 성능 이 좋 지 않 습 니 다.이 코드 를 실행 하지 마 십시오.쉽게 컴퓨터 를 다시 시작 할 수 있 습 니 다.메모 리 를 너무 많이 먹 으 면 순환 횟수 를 줄 일 수 있 습 니 다.

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;
  }
}
방법 영역 테스트 인터페이스:

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]
처리 방법,Metaspace 의 크기 를 설정 합 니 다.예 를 들 어-XX:MetaspaceSize=64M-XX:MaxMetaspaceSize=512 M
자바 가상 컴퓨터 스 택
앞에서 학습 하면 자바 가상 머 신 스 택 은 스 택 프레임 방식 으로 저장 되 고 한 방법 은 스 택 프레임 에 대응 하 며 대기 열 모드 에 따라 스 택 에 들 어가 기 때문에 테스트 프로그램 으로 인해 자바 가상 머 신 스 택 에 문제 가 생 겼 으 며 재 귀 방법 으로 테스트 할 수 있 습 니 다.

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,창고 넘 침 이상:
java.lang.StackOverflowError: null
at com.example.jvm.jvmexceptionexample.controller.StackController.add(StackController.java:14) ~[classes/:na]
처리 방법,설정-Xss 256 k:스 레 드 마다 스 택 크기 를 설정 합 니 다.JDK 5 이후 각 스 레 드 스 택 의 크기 는 1M 이 고 이전 스 레 드 스 택 의 크기 는 256 K 입 니 다.
이상 은 JVM 시리즈 의 메모리 모델 에 대한 상세 한 내용 입 니 다.JVM 메모리 모델 의 메모리 구조 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기