자바 가상 컴퓨터 스 택 및 메모리 모델 깊이 이해
스 택 프레임:모든 스 택 프레임 은 호출 된 방법 에 대응 하여 하나의 방법의 운행 공간 으로 이해 할 수 있 습 니 다.
모든 스 택 프레임 에는 부분 변수 표(Local Variables),작업 스 택(Operand Stack),실행 시 상 당량 풀 을 가리 키 는 참조(A reference to the run-time constant pool),방법 반환 주소(Return Address)와 추가 정보 가 포함 되 어 있 습 니 다.
부분 변수 표:방법 에서 정 의 된 부분 변수 와 방법의 매개 변 수 는 이 표 에 저장 되 어 있 습 니 다.부분 변수 표 의 변 수 는 직접 사용 할 수 없습니다.만약 에 사용 하려 면 관련 명령 을 통 해 이 를 조작 수 스 택 에 불 러 와 조작 수 로 사용 해 야 합 니 다.
작업 수 스 택:스 택 을 누 르 고 스 택 을 나 가 는 방식 으로 작업 수 를 저장 합 니 다.
동적 링크:모든 스 택 프레임 은 런 타임 풀 에서 이 스 택 프레임 에 속 하 는 방법 에 대한 인용 을 포함 하고 있 습 니 다.이 인용 을 가지 고 있 는 것 은 방법 호출 과정 에서 의 동적 연결(Dynamic Linking)을 지원 하기 위해 서 입 니 다.
방법 반환 주소:한 방법 이 실 행 된 후에 두 가지 방법 만 종료 할 수 있 습 니 다.하 나 는 방법 에 따라 되 돌아 오 는 바이트 코드 명령 입 니 다.하 나 는 이상 을 만 났 고 이 이상 은 방법 내 에서 처리 되 지 않 았 다.
class Person{
private String name="Jack";
private int age;
private final double salary=100;
private static String address;
private final static String hobby="Programming";
public void say(){
System.out.println("person say...");
}
public static int calc(int op1,int op2){
op1=3;
int result=op1+op2;
return result;
}
public static void order(){
}
public static void main(String[] args){
calc(1,2);
order();
}
}
Compiled from "Person.java" class Person {
...
public static int calc(int, int);
Code:
0: iconst_3 // int 3 [ ]
1: istore_0 // int [ 0]
2: iload_0 // [ 0] int
3: iload_1 // [ 1] int
4: iadd // , int ,
【For example, the iadd instruction (§iadd) adds two int values together. It requires that the int values to be added be the top two values of the operand stack, pushed there by previous instructions. Both of the int values are popped from the operand stack. They are added, and their sum is pushed back onto the operand stack. Subcomputations may be nested on the operand stack, resulting in values that can be used by the encompassing computation.】
5: istore_2 // int [ 2]
6: iload_2 // [ 2] int
7: ireturn // int
...
}
2.깊이 분석
2.1 스 택 지향 더미
만약 에 스 택 프레임 에 변수 가 있 으 면 유형 은 참조 형식 입 니 다.예 를 들 어 Object obj=new Object()는 전형 적 인 스 택 에서 요소 가 쌓 인 대상 을 가리 키 는 것 입 니 다.
2.2 방법 영역 지향 더미
방법 영역 에 정적 변수,상수 등 데 이 터 를 저장 합 니 다.아래 와 같은 상황 이 라면 전형 적 인 방법 구역 에서 요소 가 더미 속 의 대상 을 가리 키 는 것 이다.
private static Object obj=new Object();
2.3 더미 지향 방법 영역
방법 구역 에는 클래스 의 정보 가 포함 되 어 있 습 니 다.더미 에 대상 이 있 습 니 다.대상 이 어떤 클래스 로 만 들 어 졌 는 지 어떻게 압 니까?
사고:대상 이 어떤 종류 로 만 들 어 졌 는 지 어떻게 압 니까?어떻게 기록 합 니까?자바 대상 에 대한 구체 적 인 정 보 를 알 아야 합 니 다.
2.4 Java 개체 메모리 레이아웃
하나의 자바 대상 은 메모리 에 세 부분 을 포함 합 니 다.대상 헤드,인 스 턴 스 데이터 와 정렬 충전 입 니 다.
3.메모리 모델
3.1 도해
하 나 는 시비 더미 구역 이 고,하 나 는 더미 구역 이다.
더 미 는 두 개의 큰 덩어리 로 나 뉘 는데 하 나 는 Old 구역 이 고 하 나 는 Young 구역 이다.영 은 두 개의 큰 덩어리 로 나 뉘 는데 하 나 는 서 바 이 버 구역(S0+S1)이 고 하 나 는 에덴 구역 이다.Eden:S0:S1=8:1:1 S10 은 S1 만큼 크 고 From 와 To 라 고도 할 수 있 습 니 다.
이전 힙 에 대한 설명 을 통 해 알 수 있 듯 이 일반 대상 과 배열 의 생 성 은 더미 에서 메모리 공간 을 분배 합 니 다.관건 은 더미 에 이렇게 많은 구역 이 있 는데 그 대상 의 생 성 은 도대체 어느 구역 에 있 습 니까?
3.2 대상 이 있 는 영역 만 들 기
일반적으로 새로 만 든 대상 은 Eden 구역 에 배정 되 고 일부 특수 한 큰 대상 은 Old 구역 에 직접 배정 된다.
예 를 들 어 대상 A,B,C 등 이 Eden 구역 에 만 들 어 졌 지만 Eden 구역 의 메모리 공간 은 한계 가 있 을 것 입 니 다.예 를 들 어 100 M 을 사 용 했 거나 설 정 된 임계값 에 이 르 렀 다 면 Eden 메모리 공간,즉 쓰레기 수집(Garbage Collect)을 청소 해 야 합 니 다.이런 GC 를 우 리 는 Minor GC 라 고 부 릅 니 다.Minor GC 는 Young 구역 의 GC 를 말 합 니 다.
GC 를 거 친 후에 일부 대상 은 정리 되 고 일부 대상 은 살아 있 을 수 있 으 며 살아 있 는 대상 에 대해 서 는 Survivor 구역 으로 복사 한 다음 에 Eden 구역 의 이 대상 들 을 비 워 야 한다.
3.3 Survivor 구역 에 대한 상세 한 설명
도 해 를 보면 Survivor 는 두 개의 S0 과 S1 로 나 뉘 는데 From 와 To 라 고도 할 수 있다.같은 시점 에서 S0 과 S1 은 한 구역 만 데이터 가 있 을 수 있 고 다른 하 나 는 비어 있다.
이 어 위의 GC 의 경우 처음에 Eden 구역 과 From 에 만 대상 이 있 었 고 To 중 은 비어 있 었 다.이때 GC 작업 을 한 번 하면 From 구역 에서 대상 의 나이 가+1 이 되 고 우 리 는 Eden 구역 에서 살아 남 은 모든 대상 이 To 구역 으로 복 사 될 것 이라는 것 을 알 고 있 습 니 다.
From 구역 에서 살아 남 을 수 있 는 대상 은 두 곳 이 있 을 것 이다.
대상 연령 이 이전에 설정 한 연령 한도 값 에 도달 하면 대상 은 Old 구역 으로 이동 하고,1113088:1113089:Eden:1113090:1113091:From:1113090:한도 값 에 도달 하지 못 한 대상 은 To 구역 으로 복 사 됩 니 다.이때 에덴 구 와 프 롬 구 는 이미 비 워 졌 다.
이때 From 와 To 는 캐릭터 를 주 고 받 았 고,이전의 From 는 To 로,이전의 To 는 From 로 바 뀌 었 다.어떻게 든 To 라 는 Survivor 구역 이 비어 있다 는 것 을 보증 해 야 한 다 는 것 이다.
마 이 너 GC 는 To 구역 이 채 워 질 때 까지 이러한 과정 을 반복 한 뒤 모든 대상 을 옛날 로 복사 합 니 다.
3.4 오래된 지역 에 대한 상세 한 설명
위의 분석 을 통 해 알 수 있 듯 이 일반 Old 구역 은 나이 가 비교적 많은 대상 이거 나 특정한 한도 값 을 상대 적 으로 초과 한 대상 이다.
Old 구역 에서 도 GC 의 조작 이 있 습 니 다.Old 구역 의 GC 는 Major GC 라 고 합 니 다.
3.5 대상 의 평생 이해
저 는 평범한 자바 대상 입 니 다.저 는 Eden 지역 에서 태 어 났 습 니 다.Eden 지역 에서 저 와 닮 은 동생 도 보 았 습 니 다.우 리 는 Eden 지역 에서 오랫동안 놀 았 습 니 다.어느 날 Eden 구역 에 사람 이 너무 많아 서 저 는 Survivor 구역 의'From'구역 에 갈 수 밖 에 없 었 습 니 다.Survivor 구역 에 간 후부 터 저 는 표류 하기 시 작 했 습 니 다.가끔 은 Survivor 의'From'구역 에 있 고 가끔 은 Survivor 의'To'구역 에 있 으 며 정처 가 없 었 습 니 다.내 가 열 여덟 살 이 되 었 을 때 아버 지 는 내 가 성인 이 되 었 으 니 사회 에 나 가 야 한다 고 말씀 하 셨 다.그래서 저 는 늙 은 세대 에 갔 습 니 다.늙 은 세대 에 사람 이 많 고 나이 도 많 습 니 다.저 는 여기 서 많은 사람들 을 알 게 되 었 습 니 다.연로 한 세대 에 나 는 20 년(매번 GC 에 한 살 씩)을 살다 가 회수 되 었 다.
3.6 흔히 볼 수 있 는 문제
Minor GC:신세대
주요 GC:구세대
Full GC:신세대+노년기
옛 시대 의 공간 을 늘 리 거나 적 게 만 들 겠 다 고 말 할 수도 있다.옛 시대 의 공간 을 늘 려 야 더 많은 생존 대상 이 옛 시 대 를 채 울 수 있다.풀 GC 주파 수 를 낮 추 긴 했 지만,노후 공간 이 커지 면서 풀 GC 가 발생 하면 실행 에 걸 리 는 시간 이 더 길 어 졌 다.
노후 공간 을 줄 이면 풀 GC 에 걸 리 는 시간 은 줄 어 들 지만,노후 에는 곧 생존 대상 으로 채 워 져 풀 GC 주파수 가 증가한다.
그래서 Survivor 의 존재 의 미 는 바로 옛날 로 보 내 지 는 대상 을 줄 이 고 Full GC 의 발생 을 줄 이 는 것 이다.Survivor 의 예비 선별 보증 은 16 번 의 Minor GC 를 거 쳐 신세대 에서 살아 남 을 수 있 는 대상 만 옛날 로 보 내 지 는 것 이다.
새로 만 든 대상 은 Eden 에 있 습 니 다.Eden 이 가득 차 면 Minor GC 를 한 번 터치 하면 Eden 의 생존 대상 은 Survivor 구역 으로 이동 합 니 다.이렇게 계속 순환 하면 다음 에덴 이 꽉 찼 을 때 문제 가 생 겼 다.이때 Minor GC,Eden 과 Survivor 는 각각 생존 대상 이 있다.만약 에 이때 Eden 구역 의 생존 대상 을 Survivor 구역 에 억지로 두 면 이 두 부분 대상 이 차지 하 는 메모리 가 계속 되 지 않 고 메모리 파편 화 를 초래 한 것 이 분명 하 다.
영원히 하나의 Survivor space 는 비어 있 고,다른 하 나 는 비어 있 지 않 은 Survivor space 는 조각 이 없다.
사용 가능 한 메모리 중 Eden:S1 구역 은 8:1 입 니 다.
즉 신생대 중 에덴:S1:S2=8:1:1
4.검증
4.1 더미 메모리 넘 침
프로그램:
@RestController
public class HeapController {
List<Person> list=new ArrayList<Person>();
@GetMapping("/heap")
public String heap() throws Exception{
while(true){
list.add(new Person());
Thread.sleep(1);
}
}
}
인 자 를 설정 하 세 요.예 를 들 어-Xmx20M-Xms20M.실행 결과:
Exception in thread "http-nio-8080-exec-2" java.lang.OutOfMemoryError: GC overhead limit exceeded
4.2 방법 영역 메모리 넘 침예 를 들 어 방법 영역 에 Class 정 보 를 추가 합 니 다.
4.2.1 asm 의존 과 Class 코드
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
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();
Metaspace test = new Metaspace();
byte[] code = cw.toByteArray();
Class<?> exampleClass = test.defineClass("Class" + i, code, 0, code.length);
classes.add(exampleClass);
}
return classes;
}
}
4.2.2 코드
@RestController
public class NonHeapController {
List<Class<?>> list=new ArrayList<Class<?>>();
@GetMapping("/nonheap")
public String nonheap() throws Exception{
while(true){
list.addAll(MyMetaspace.createClasses());
Thread.sleep(5);
}
}
}
Metaspace 의 크기 를 설정 합 니 다.예 를 들 어-XX:MetaspaceSize=50M-XX:MaxMetaspaceSize=50M실행 결과:
java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_191]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_191]
4.3 가상 컴퓨터 스 택4.3.1 코드 데모 StackOverFlow
public class StackDemo {
public static long count=0;
public static void method(long i){
System.out.println(count++);
method(i);
}
public static void main(String[] args) {
method(1);
}
}
실행 결과:4.3.2 이해 와 설명
Stack Space 는 재 귀적 호출 을 할 때 Stack Frame(스 택 프레임)을 누 릅 니 다.따라서 재 귀적 호출 이 너무 깊 을 때 Stack Space 를 다 소모 하여 Stack Overflow 의 오 류 를 폭로 할 수 있 습 니 다.
-Xss 128 k:스 레 드 마다 스 택 크기 를 설정 합 니 다.JDK 5 이후 모든 스 레 드 스 택 크기 는 1M 이 고 이전 에는 스 레 드 스 택 크기 가 256 K 였 습 니 다.응용 스 레 드 에 필요 한 메모리 크기 를 조정 합 니 다.같은 물리 적 메모리 에서 이 값 을 줄 이면 더 많은 스 레 드 를 만 들 수 있 습 니 다.그러나 운영 체 제 는 한 프로 세 스 의 스 레 드 수 에 제한 이 있어 무한 생 성 이 불가능 하고 경험 치 는 3000~5000 정도 입 니 다.
스 레 드 스 택 의 크기 는 양날 의 검 입 니 다.너무 작 게 설정 하면 스 택 이 넘 칠 수 있 습 니 다.특히 이 스 레 드 에 재 귀적 이 고 큰 순환 이 있 을 때 넘 칠 가능성 이 더 큽 니 다.이 값 을 너무 크게 설정 하면 스 택 을 만 드 는 수량 에 영향 을 줄 수 있 습 니 다.다 중 스 레 드 를 사용 하면 메모리 가 넘 치 는 오류 가 발생 할 수 있 습 니 다.
자바 가상 머 신 스 택 과 메모리 모델 에 대해 깊이 있 게 알 고 있 는 이 글 은 여기까지 소개 되 었 습 니 다.자바 가상 머 신 스 택 과 메모리 모델 에 관 한 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.