- 자바 프로그램이 실행되는 가상 머신
- 자바 어플리케이션이 어느 CPU나 OS에서도 실행될 수 있게 지원
기존의 컴파일 언어
- 프로그래밍 언어가 컴파일되는 시점에서, 해당 운영체제에 맞는 binary code로 변환된다.
vs
JVM
- 자바가 컴파일되는 시점에서는 java code -> java bytecode로 변환됨
- java bytecode는 실행 시점에 JVM에 의해 실행된다.
- JVM (Java Virtual Machine)
- JRE (Java Runtime Environment) : JVM + 표준 라이브러리
- JDK (Java Dev Kit) : JRE + 컴파일러 등 개발환경에 필요한 요소들
- 어플리케이션 실행 -> JVM이 OS로부터 메모리를 할당받는다.
- 자바 컴파일러가 자바 소스코드(.java)를 바이트코드(.class)로 변환
- Class Loader에서 바이트코드를 JVM으로 로딩한다.
- Execution Engine에서 바이트코드가 해석된다.
- 해석된 코드를 Runtime Data Area가 실행한다.
-
Constant Pool
-
Bytecode
- Loading
- .class 코드 로딩
- 한번에 모든 클래스를 올리지 않고, 필요할 때 동적으로 올림
- Linking
- 클래스 간 연결구조 설정
- Initialization
- Runtime Data Area에 배치
- Method Area (모든 스레드 공유)
- 클래스와 관련된 모든 정보가 저장된다.
- Runetime Constant Pool : 상수 자료형을 저장하여 참조하는 역할
- Heap (모든 스레드 공유)
- 런타임에 생성되는 모든 객체가 저장된다
- 객체의 생성 및 소멸 처리
- Young Generation : 생명주기가 짧은 객체 / Old Gen : 생명주기가 긴 객체
- GC에 의해 지속적으로 메모리가 관리됨
- Minor GC
- Major GC
- JVM Stack (스레드별로 생성)
- 메서드 호출과 관련된 정보를 저장한다.
- 메서드가 호출될 때마다 Stack Frame 생성
- 해당 메서드의 매개변수, 지역 변수, 메서드 호출 및 복귀 주소 등 저장
- 프레임 구조
- 지역변수 : Array의 형태로 저장되어 접근 가능
- Operand Stack : 연산의 중간 결과물을 저장하는 stack
- GC를 수행하기 위해 JVM이 멈추는 현상
- GC 관련 Thread를 제외한 모든 thread는 멈춘다
- 이 시간을 최소화하는 것이 튜닝의 목적!!
- 대부분의 객체는 금방 불가능한 상태가 된다.
- 하나의 중괄호 {} 안에서 생성되고 사용종료되는 경우가 많음
- 오래된 객체에서 젊은 객체로의 참조는 아주 적게 발생
- 코드가 순차적으로 실행되기 때문
- 더이상 참조되지 않는 객체에 대해 소멸 가능
-> 따라서 Heap Area에서 더이상 사용하지 않는 객체를 소멸하는 작업이 필요하다!
- Young Generation : 생명주기가 짧은 객체 - Old Gen : 생명주기가 긴 객체 - Minor GC - Major GC- 객체가 생성되면 Eden 영역에 생성됨
- Minor GC
- 미사용 객체 제거
- 사용되는 객체는 Servivor 영역(S1,S2)로 이동 (큰 객체는 바로 OG로 이동)
- S1과 S2 중 한곳은 비워져 있는 상태, 한 곳이 가득 차면 다른 영역으로 보내고(To), 기존 영역 비움(From)
- 1~3 반복 -> Servivor 영역에서 살아남은 객체에 score 누적됨 -> 기준치 이상일경우 OG로 이동 (=Promotion)
- OG에 객체가 일정 수준 이상 쌓일경우, Major GC 발생, STW 발생
- Reference Counting Algorithm : 각 객체마다 Ref Count 관리, 0이 되면 제거
- 카운트가 0이 되면 바로 사라지는 장점
- 순환 참조에서는 0이 되지 않음
- Mark-and-Sweep Algorithm
- Mark : GC 대상이 아닌 객체를 마킹
- Sweep : 마킹되지 않은 객체를 삭제
- Compaction 작업이 없음 -> 메모리 단편화로 인한 memory 초과 문제 발생
- Mark-and-Compact Algorithm
- Mark : GC 대상이 아닌 객체를 마킹
- Sweep : 마킹되지 않은 객체를 삭제
- Compact : 메모리의 빈 공간 제거
- 메모리 효율 증가 / 작업량이 많아 오버헤드 발생 가능
- Copying Algorithm
- Concurrent Mark-Sweep Algorithm
- Generational Algorithm
- Serial GC
- 하나의 CPU로 처리
- Mark-and-Compact Algorithm
- GC에서 STW 발생
- Parallel GC
- default in java 7~8
- 병렬처리 -> STW 짧음
- CMS GC (Concurrent Mark-Sweep)
- 병렬처리 -> STW 짧음
- Mark-and-Sweep Algorithm -> 메모리 단편화 발생
- G1 GC
- 고용량, 대규모에 �짧은 GC시간 보장
- Heap영역이 Region이라는 하위 영역으로 분할하여 실행됨 -> 전체 GC시간 단축
- 메모리 역할(Eden,OG,S1,S2,YG) 이 동적으로 부여됨
- Z GC
- ZPage 영역 사용 -> Region이 2MB의 배수로 유동적
- 정지시간 10ms 초과되지 않음을 보장
- Heap 크기가 증가하더라도 정지시간이 증가하지 않음
디폴트 : Parallel GC 튜닝할 경우 : 보통 CMS GC, G1 GC 사용