모든 소스코드들은 실행하기 전에 컴파일이나 인터프리트 과정을 거쳐야한다
JAVA에서는 프로그램을 실행하는데 있어서 두 가지를 모두 사용한다
💡 ByteCode : JVM 전용 기계어
JVM은 해당 이진 ByteCode를 동작하는 플랫폼에 맞는 기계어로 변환한다
JVM은 기존 프로세스위에서 동작하는 가상의 기계역할을 하며 Java API와 함께 Java 개발을 할 수 있도록 만들어주고 다음과 같이 정의할 수 있다
JVM은 Main 메서드를 찾아서 실행시키고, 플랫폼에 무관하게 자바 어플리케이션이 동작하게 해준다
.java 파일을 컴파일하여 바이트코드로 이루어진 .class파일을 생성하고 실행시킨다
JVM이 처리해주는 작업들은 다음과 같다
.class
형식 제공크게 ClassLoader / Memory 영역 / 실행엔진 으로 나뉘어서 동작한다
ClassLoader
.class 파일들을 읽고, 검증한다음 초기화하는 작업을 수행한다
이러한 과정을 Loading / Linking / Initialization 으로 부른다
Memory 영역
크게 Method( Static ) / Heap / Stack / PC 레지스터 / Native Method Stack 으로 나뉜다
이 중 중요한 부분은 Method / Heap / Stack 영역이다
실행엔진
메모리에서 데이터를 읽고 실행하는 역할을 한다
Interpreter나 Garbage Collector, JIT 컴파일러 등이 있다
앞서 설명한 Garbage Collector가 실행하는 프로세스로 메모리관리에 사용된다
더이상 Heap영역에 필요없는 객체를 처리하는 작업이다
객체의 자원회수를 자동으로 해주기때문에 부주의로 인한 메모리낭비를 줄일 수 있다는 장점이 있지만,
자원 회수시점과 상태추적에 들어가는 자원소모가 있다는 단점도 있다.
GC가 적용되는 대상은 더이상 아무런 곳에서도 참조하지않는 객체이다
주로 null을 명시해줌으로써 GC대상이 되게 할 수 있다
GC의 주요특징으로는 STW( Stop thw World ) 가 있다
이는 GC작업이 완료될 때까지 Thread가 정지함을 의미한다.
Heap영역은 크게 Young Gen / Old Gen으로 나뉘는데 각각 아래와 같다
Young Generation
새로운 객체가 할당되는 영역으로 이 영역에 객체가 가득차면 Minor GC가 진행되고 속도가 빠르다
Old Generation
오랫동안 살아남은 객체들을 저장하는 영역으로 Young Generation보다 크다
Young Generation에서 특정 시간이상 살아남은 객체들이 이 영역으로 옮겨진다
이 영역에서 일어나는 Collection을 Major GC라고 부르며 STW시간이 더 길다
두 가지 영역 모두를 대상으로한 GC는 Full GC라고 부른다
이때, Young Generation은 Eden, Survivor 으로 나뉜다
Eden은 최초에 저장되는 영역이고 Survivor는 Eden이 가득찬 다음, GC가 일어나고 살아남은 객체가 저장되는 영역이다
싱글 스레드환경에서 동작
Young 영역에서는 앞서 설명한 것처럼 동작하고 Old 영역에서는 mark-sweep-compact 알고리즘을 사용한다
1. **살아있는 객체 식별 ( Mark )**
2. **Mark 하지 않은 객체 제거 ( Sweep )**
3. **살아있는 객체를 앞쪽부터 채우기 ( Compaction )**
의 과정으로 동작하며 그림으로 설명하면 다음과 같다
Serial GC와 동일하게 동작하나 멀티스레드 환경에서 동작한다
Concurrent Mark-Sweep GC
위 구조에서 GC가 일어나면 겪게되는 과정을 알아보자
Survivor 에서 특정시간 이상 살아남은 객체들은 Old Generation으로 옮겨지고 나머지 객체들은 또 다른 Survivor 영역으로 이동된다
Old Generation 에서는 2번의 STW 이벤트가 발생한다
이후 2번의 STW이벤트를 거친후에 mark되지 않은 모든 객체들의 메모리를 반환시킨다
모든 과정에서 full GC가 일어나지 않는이상 압축은 하지않는다
이름이 G1( Garbage First ) 인 이유는 Garbage만 있는 지역을 먼저 회수해서다
CMS GC를 더 효율적으로 만든 버전이다
기본적으로 Minor GC만 수행된다
만약 Old gen 비율이 임계 값을 초과하면 Major GC와 Minor GC가 왔다갔다 하면서 동작한다
이후 Space Reclamation 단계에 진입하게되면 Mixed GC가 수행된다
💡 Mixed GC
Young / Old 영역 모두의 Garbage 수집
Minor GC + Old 영역 GCMixed GC는 아래의 과정을 거친다
Young / Old Generation으로 나누지않고, 일정한 크기의 region으로 나눈다
이 region의 크기는 JVM을 시작할때 설정할 수 있으며 일반적으로 1~32mb크기를 가진 약 2000개의 region으로 나눈다
region들은 개념적으로 Eden, Survivor, Old Generation, Humongous로 나눌 수 있다
먼저 Eden과 Survivor 영역에 해당하는 region에 대해 Minor GC가 일어나면 STW가 발생하고
살아남은 객체들은 적절한 크기의 Old Generation이나 survivor로 이동된다
이 작업은 멀티스레드 환경에서 병렬적으로 이루어진다
Minor GC 가 끝날때까지 Old에서 참조하는 survivor region이 있는지를 찾고 해당 reigon에서 생존한 객체를 찾아 mark한다