오늘은 JVM에 대해서 알아본다.
Java Virtual Machine의 약자
Java 프로그램이 실행되는 가상 머신을 의미
내부적으로 thread 및 메모리를 관리해 하나의 컴퓨터처럼 동작한다.
java 코드가 컴파일된 class 파일을 읽어서 실행
java의 기본 특징 write once, run everywhere를 보장하기 위한 수단
메모리 관리 및 다양한 운영체제에서의 호환성을 위해 사용됨
JVM은 class 파일을 jvm machine instruction을 해석해서 동작
Java 언어의 한계를 극복하고자, 문법이 더 좋게 만들어진 언어들도 그 결과물을 class 파일로 만들어 JVM에서 동작하도록 함
이러한 전략들을 통해 JVM은 더욱 다양한 분야에서 사용되고 있음
이러한 언어들로는 Groovy, Scala, Kotlin 등이 있음
Stack Area
JVM에서 스레드를 생성하면 stack 영역이 자동으로 생성. 해당 스레드 안에서만 사용할 수 있는 stack 자료구조.
Local Variadble Array : 해당 스레드에서 필요한 지역변수들을 array로 저장
Operand Stack : 계산의 중간 결과물 저장
Frame Data : 상수 풀과 excpetion table을 가짐
PC Register
Native Method Area
Shared Memory(JVM Heap)
모든 스레드에서 공유되는 자원
메소드와 Heap 영역의 분리는 논리적인 개념의 구분임
메소드 영역 : class, method, static variables 등을 저장. 불변
Heap 영역 : Java object들의 저장소. GC의 대상이 되는 영역.
Metadata Space
변하지 않는 정보(Class, Method, static 변수)를 저장
GC의 대상이 아님
Eden Space(Young Gen)
객체가 생성되면 위치하는 공간
Minor GC, Full GC의 대상 공산
Survivor Space(Young Gen)
Eden의 객체가 GC에서 살아남으면 위치하는 공간
Space 0과 1은 교차되며 저장하고 비운다.
Minor GC, Full GC의 대상 공간
Tenured Space(Old Gen)
Young Gen에서 오래 살아남은 객체가 최종적으로 머무는 공간
Major GC, Full GC의 대상 공간
Old Gen의 사용량/점유율이 높을수록 GC에 의해 성능의 부하가 크다.
최소 메모리(Xms128m) : JVM이 기동할 때 필요한 메모리 공간
최대 메모리(Xmx128m) : xms로 시작해서 최대 도달 가능한 메모리 공간. 보통 xms와 xmx를 같게 설정하여 모니터링 및 운영을 쉽게 할수 있도록 함
GC의 과정
Minor GC
New object는 Eden에서 생성
Eden이 가득차면 minor GC가 수행됨
GC 이후 살아남은 객체는 비어있는 Survivor-1 영역으로 이동
몇 번의 minor GC에도 살아남은 Survivor-1 영역의 객체는 Old Gen 영역으로 이동
Eden과 survivor-0은 비워짐
여기서 또 한번의 minor GC가 일어나면 Survivor-0과 Survivor-1의 역할이 바뀌며 같은 동작을 반복한다.
Eden → Survivor에서 Memory copy가 발생
Survivor → Old Gen에서 Memory copy가 발생
Major GC
Full GC
하지만 알고리즘이 모든 것을 보장해주지는 않음. 객체의 주기를 짧게 가져가도록 프로그래밍하고, 오래 살아남는 객체를 최소화 하면 Full GC가 최소한으로 일어나도록 할 수 있음
Graph
Mark : GC root에서 시작해서 참조하는 객체를 찾아가며 Mark
Sweep : Mark되지 않은 객체는 제거
Compact : Sweep에 의해 발생된 Fragmentation을 정리(연속된 메모리 공간으로 재할당)
GC root가 되는 항목들
JVM stack의 변수
Method Area의 static 데이터
JNI에서 생성된 객체
Serial GC
싱글 스레드
느리고 STW가 길다
Mark, Sweep, Compact를 사용
Parallel GC
Young Gen의 GC를 멀티 스레드로
Serial GC에 비해 STW가 짧음(그림 참조)
ParallelOldGC는 old 영역까지 멀티 스레드로
Java 7, 8의 기본 GC
CMS GC
STW를 줄이기 위해 만든 GC
Mark를 4단계로 구분해서 수행
단점
설정
G1 GG
CMS의 Fragmentation을 줄이고, GC 부하를 낮추기 위해 고안
Region 단위로 블럭을 나누어 관리(논리적 구분)
가득 차거나 Garbage가 많은 Region만 GC의 대상임
한 번에 young 및 old의 모든 영역을 GC하지 않음으로 빠르게 처리됨
Memoty Fraction이 적음
Minor GC
Major GC
설정