|
| 1 | +# 자바 프로그램이 실행되는 흐름 |
| 2 | + |
| 3 | +## 실행 흐름 |
| 4 | +### 1. 컴파일 |
| 5 | +* 개발자가 작성한 `.java` 파일은 JDK에 포함된 **java compiler**를 통해 컴파일 됨 |
| 6 | +* 그럼 JVM이 이해할 수 있는 `.class` **바이트 코드**로 변환됨 |
| 7 | +### 2. JVM에서의 실행 |
| 8 | +* 클래스 로더가 바이트 코드를 JVM 메모리에 동적으로 로드 |
| 9 | +* 로딩, 링킹, 초기화 단계를 거치고 로드된 바이트 코드는 Method Area에 저장됨 |
| 10 | +* 실행 엔진(인터프리터, JIT 컴파일러)를 통해 바이트 코드를 기계어로 변환하여 실행 |
| 11 | + |
| 12 | +## 클래스 로더의 바이트 코드 동적 로드 |
| 13 | +* 프로그램이 실행될 때 모든 클래스를 한꺼번에 로드하는 것이 아니라, 런타임 시점에 필요한 클래스만 로드 |
| 14 | +* 인스턴스 생성, static 메서드나 변수 사용, static 변수에 값을 할당할 때 |
| 15 | +* 불필요한 클래스 로드를 방지하여 메모리를 효율적으로 사용할 수 있음 |
| 16 | + |
| 17 | +## 로딩, 링킹, 초기화 |
| 18 | +### 로딩 |
| 19 | +* 로딩(Loading)은 클래스 로더가 `.class` 파일을 열어 JVM 메모리에 로드하는 단계 |
| 20 | +* 로드된 클래스는 Method Area에 저장됨 |
| 21 | + |
| 22 | +### 링킹 |
| 23 | +* 링킹(Linking)은 로드된 클래스가 실행될 수 있도록 준비하는 단계이며 세 가지의 과정으로 이루어짐 |
| 24 | + * Verification : `.class` 파일이 구조적으로 올바른지 확인 |
| 25 | + * Preparation : static 변수를 메모리에 할당하고 기본값으로 초기화 |
| 26 | + * Resolution : 런타임 상수 풀에 있는 심볼릭 레퍼런스를 실제 메모리 레퍼런스로 교체 |
| 27 | + |
| 28 | +### 초기화 |
| 29 | +* 초기화(Initialization)는 static 변수를 사용자가 지정한 값으로 초기화하고 static 블록을 실행하는 단계 |
| 30 | + |
| 31 | +## 실행 엔진이 바이트 코드를 기계어로 변환 시 인터프리터와 JIT 컴파일러를 함께 사용하는 이유 |
| 32 | +* JVM은 인터프리터와 JIT 컴파일러를 모두 사용하여 초기 실행 속도와 높은 반복 실행 성능을 동시에 달성함 |
| 33 | + |
| 34 | +### 인터프리터 |
| 35 | +* 바이트 코드를 한 줄씩 읽어서 실행하는 방식이기 때문에 초기 실행 속도가 빠름 |
| 36 | +* 하지만 같은 코드가 반복적으로 실행될 경우 매번 해석해야 해서 성능이 저하됨 |
| 37 | +* 초기 JVM은 인터프리터만 사용했지만, 이러한 단점을 보완하기 위해 JIT 컴파일러가 도입됨 |
| 38 | + |
| 39 | +### JIT 컴파일러 |
| 40 | +* 자주 실행되는 메서드를 네이티브 코드로 변환하여 캐싱 → 반복 실행 시 인터프리터보다 훨씬 빠르게 실행 가능 |
| 41 | +* 하지만 JIT 컴파일 과정 자체에 시간이 소요되기 때문에 초기 실행 시 오버헤드가 발생할 수 있음 |
0 commit comments