owned this note
owned this note
Published
Linked with GitHub
# Java Virtual Machine (JVM)

- 자바 가상 머신 JVM(Java Virtual Machine)은 자바 프로그램 실행환경을 만들어 주는 소프트웨어다
- 자바를 실행하기 위한 가상 기계
- Java 는 OS에 종속적이지 않다는 특징을 가지고 있다. OS에 종속받지 않고 실행되기 위해선 OS 위에서 Java 를 실행시킬 무언가가 필요하다. 그게 바로 JVM이다.
- 즉, OS에 종속받지 않고 CPU 가 Java를 인식, 실행할 수 있게 하는 가상 컴퓨터이다
- 즉, JVM은 자바 프로그램이 실행되는 **표준 환경**을 제공한다
## 자바 실행 과정

자바의 실행 과정은 다음과 같은 단계로 이루어진다
1. **컴파일 단계**: 자바 컴파일러(`javac`)가 자바 소스코드(`.java` 파일)를 읽어들여 자바 바이트코드(`.class` 파일)로 변환한다. 이 과정에서 문법 검사와 기타 컴파일 타임 체크가 이루어진다.
2. **로딩 단계**: Class Loader가 `.class` 파일들을 JVM으로 로딩한다. 이 과정에서 클래스의 바이트코드가 메모리에 로드되며, 필요한 경우 링크 과정을 통해 다른 클래스와의 참조를 확인하고 연결한다.
3. **실행 단계**: 로딩된 `.class` 파일들은 Execution engine을 통해 해석된다. Execution engine은 바이트코드를 한 단위씩 읽어들여 해당하는 기계어로 변환하고 실행한다. 이 과정에서 Just-In-Time 컴파일러를 사용하여 효율적인 실행을 지원한다.
4. **런타임 단계**: 해석된 바이트코드는 Runtime Data Areas에 배치되어 실질적인 수행이 이루어진다. 이 영역에는 메소드 영역, 힙 영역, 스택 영역 등이 포함되며, 각각의 영역은 특정한 목적으로 사용됩니다.
5. **종료 단계**: 프로그램이 종료되거나, `System.exit()` 메소드를 호출하여 명시적으로 종료되면 프로그램이 종료된다.
6. **자바 가상 머신 종료**: 프로그램이 종료되면 JVM은 자원을 회수하고 종료된다.
## 가비지 컬렉션 (Garbage Collection, GC)
- 개요
- 프로그램이 동작하다보면 유효하지 않은 메모리인 가바지(Garbage)가 발생하게 된다. 유효하지 않은 메모리를 반환하기 위해서는 직접 메모리를 반환하거나 GC를 이용한다.
- 언매니지드 프로그래밍 언어(C, C++ 등)를 이용하면 직접 메모리를 해제해주어야 한다
- 매니지드 프로그래밍 언어(Java, Python 등)를 이용하면 **GC**를 통해 메모리를 해제한다.
- 정의 : GC는 JVM(Java Virtual Machine)의 메모리 관리 기능 중 하나로 힙 영역에서 더 이상 사용되지 않는 객체를 자동으로 회수하여 메모리를 확보한다
- 주요 기능
- 메모리 자동 회수: 더 이상 참조되지 않는 객체를 찾아 메모리를 자동으로 해제한다. 이로 인해 프로그래머는 메모리 누수에 대한 걱정을 줄일 수 있다.
- 레퍼런스 추적: 객체들의 참조 상태를 추적하여 가비지 여부를 판단한다. 더 이상 사용되지 않는 객체는 GC 대상이 된다.
- Stop-The-World: 가비지 컬렉션 수행 시, 애플리케이션의 모든 스레드가 일시 중지된다. 이는 GC 작업이 완료될 때까지 진행된다. (Major GC)
- JVM의 Heap영역은 처음 설계될 때 다음의 2가지를 전제(Weak Generational Hypothesis)로 설계되었다.
- 대부분의 객체는 금방 접근 불가능한 상태(Unreachable)가 된다.
- 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.
## Garbage 판별
- Java는 객체가 더 이상 사용되지 않는지 판단하기 위해 **Reachability**라는 개념을 사용한다.
- Reachability는 어떤 특정 객체에 접근할 수 있는지 여부를 의미한다.
- 어떤 객체에 접근할 수 없다면, 그 객체는 Unreachable 상태가 된다.
- Unreachable 객체는 가비지 컬렉션의 대상이 된다.

## Java Heap 구조
GC는 몇 가지의 종류가 있으며 각각의 GC를 이해하기 위해서는 JVM 메모리 구조에서 동적으로 할당된 객체들이 저장되는 공간인 `Java Heap`의 구조를 알아야 한다

- 영 (Young) 영역:
- 새로 생성된 객체들이 저장되는 공간이다.
- 대부분의 객체가 금방 Unreachable 상태가 되기 때문에, 많은 객체가 Young 영역에 생성되었다가 사라진다
- 영 영역은 다시 세 개의 부분으로 나뉜다
- a. 에덴(Eden) 공간: 객체가 처음 생성되어 저장되는 영역이다.
- b. 서바이버(Survivor) 공간: 두 개의 서바이버 공간(S0, S1)으로 구성되며, 객체가 살아남은 후 옮겨지는 공간이다.
- 가비지 컬렉션 발생 시, 객체의 대부분이 사라지는 영역이며, 여기서 발생하는 GC를 마이너 GC(Minor GC)라고 한다.
- 테너드 (Tenured) 영역 또는 오래된(Old) 영역
- 오랜 시간 동안 살아남은 객체들이 저장되는 공간이다.
- 객체가 지속적으로 살아남아 영 영역에서 더 이상 담을 수 없을 때 이동된다.
- Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.
- 테너드 영역에서 발생하는 GC를 메이저 GC(Major GC) 또는 풀 GC(Full GC)라고 한다.
- 영구 (Permanent) 영역 또는 메타스페이스(Metaspace)
- 클래스 로더에 의해 로드된 클래스와 메소드의 메타데이터가 저장되는 영역이다.
- Java 8 이후, 영구 영역은 메타스페이스로 대체되었다.
- 메타스페이스는 기본적으로 네이티브 메모리를 사용하며, 영구 영역의 메모리 문제를 개선한다.
> 메타데이터(Metadata)는 데이터에 대한 데이터로, 다른 데이터의 정보와 특성을 설명하는 데이터이다
## Minor GC, Major GC, Full GC
- Minor GC
- Young 영역을 대상으로 발생하는 GC
- Major GC
- Old 영역을 대상으로 발생하는 GC
- Full GC
- 힙 영역 전체를 대상으로 발생하는 GC
- Minor GC + Major GC
- **Stop-The-World가 발생한다**
- 애플리케이션의 성능에 큰 영향을 줄 수 있다.
> Stop-The-World는 GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것을 의미한다. GC를 실행하는 스레드를 제외한 나머지 스레드들은 모두 작업을 멈추게 된다. GC 작업이 완료된 이후에야 중단했던 작업을 다시 시작한다.