JVM 시리즈 메모리 모델 상세 설명
이 장 에 서 는 자바 가상 컴퓨터 메모리 모델(자바 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: Metaspaceat 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 메모리 모델 의 메모리 구조 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
IntelliJ IDEA 2019.2의 새로운 기능 프로파일 러를 사용해 보았습니다.이번의 새로운 기능은 초호화! 저는 퍼포먼스 개선을 자주 합니다만, IntelliJ IDEA에도 프로파일링 툴이 붙게 되었으므로, 사용해 보았습니다. 편리한 것 같았기 때문에, 앞으로의 메인 웨폰은 이것이 될 것 같...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.