JVM 내부구조 와 GC 작동 형식에 대해서 자세히 알아봅시다.

자바 코드를 .class 파일로 컴파일 되고, .class 파일 위에서 실행되면서 파일에 담긴 바이트 코드를 해석하고 실행된다.
내부 구조는 클래스 로더, 런타임 데이터 영역, 실행 엔진으로 나뉜다.
클래스 로더 : 동적으로 클래스를 로딩해주는 역할 한다.자바에서 소스를 작성하면 .java파일이 생성되고 .java소스를 컴파일러가 컴파일하면 .class파일이 생성되는데 클래스 로더는 .class 파일을 묶어서 JVM이 운영체제로부터 할당받은 메모리, Runtime Data Area로 적재
실행 엔진 : JVM이 바이트 코드를 실행엔진에 제공하며 실행, 이때 로드된 바이트코드를 실행하는 런타임 모듈 이다.
런타임 데이터 영역 : JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역
실행 과정은
1. 자바 프로그램 실행하면 JVM은 OS로부터 메모리 할당된다.
2. 자바 컴파일러가 자바 소스코드(.java)를 자바 바이트 코드로(.class)로 컴파일한다.
3. Class Loader를 통해 JVM Runtime Data Area로 로딩합니다.
4. Runtime Data Area에 로딩 된 .class들은 Execution Engine을 통해 해석합니다.
5. 해석된 바이트 코드는 Runtime Data Area의 각 영역에 배치되어 수행하며 이 과정에서 Execution Engine에 의해 GC의 작동과 스레드 동기화가 이루어집니다.
JVM 내에 클래스 파일을 로드하고 링크를 통해 배치 작업을 수행하는 모듈이다.
즉, 로드된 바이트 코드들을 엮어서 JVM의 메모리 영역 (Runtime Data Areas)에 배치한다.
한번에 메모리에 올리지 않고, 어플리케이션에서 필요한 경우 동적으로 메모리에 적재하게 된다.
로딩 순서는 Lodaing(로드) -> Linking(링크) -> Initialization(초기화) 이며,
Loading : 클래스 파일을 가져와서 JVM의 메모리에 로드한다.
Linking : 검증하는과정, 여기서도 검증,준비,분석 으로 나눠진다.
검증 : 클래스가 JVM명세에 명시된 대로 구성됐는지 검사
준비 : 클래스가 필요한 메모리 할당
분석: 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경.
초기화 : 변수들을 적절한 값으로 초기화
클래스 로더를 통해 런타임 데이터 영역에 배치된 바이트 코드를 명령어 단위로 읽어서 실행한다.
바이트 코드를 JVM 내부에서 기계가 실행할수 있게 형태를 변경해주는데,
인터프리터, JIT 컴파일러 두가지 방식을 혼합해서 바이트 코드를 실행한다.
인터프리터는 명령어를 하나씩 읽어서 해석하고 실행.
JIT 컴파일러는 반복되는 코드를 발견하여 바이트 코드 전체를 컴파일하여 Native Code로 변경하고,
이후에는 해당 메소드를 더 이상 인터프리팅 하지 않고 캐싱해 두었다가 네이티브 코드로 직접 실행하는 방식이다.
JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.
크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있다.
이때 Method Area, Heap Area 는 모든 쓰레드(Thread)가 공유하는 영역이고, 나머지 Stack Area, PC Register, Native Method Stack 은 각 쓰레드 마다 생성되는 개별 영역이다.
가비지 컬렉터(garbage collector)를 이용하여 Heap 메모리 영역에서 더는 사용하지 않는 메모리를 자동으로 회수해 준다.
JAVA는 이 가비지 컬렉터를 이용해 자동으로 메모리를 실시간 최적화 시켜준다. 따라서 개발자가 따로 메모리를 관리하지 않아도 되므로, 더욱 손쉽게 프로그래밍을 할 수 있도록 해준다.