
보통 파일을 컴파일하여 실행한다? 이런거를 물어보는 것일까?
.java 파일은 JDK에 포함된 javac(java compiler)를 통해 컴파일된다.
이 과정에서 JVM이 이해할 수 있는 바이트 코드로 변환되어 .class 파일이 생성된다.
이후 JVM의 클래스 로더가 바이트 코드를 JVM 메모리에 동적으로 로드한다.
로드된 바이트 코드는 Method Area에 저장되며, 로딩, 링킹, 초기화 단계를 거친다.
그 다음 실행 엔진이 로드된 바이트 코드를 실행한다.
하지만 바이트 코드는 컴퓨터가 읽을 수 없어, 인터프리터와 JIT 컴파일러를 사용하여 기계어로 변환한다.
인터프리터는 바이트 코드를 한 줄씩 읽어서 실행하고, JIT 컴파일러는 자주 실행되는 메서드(Hotspot)를 감지하면 해당 메서드 전체를 네이티브 코드로 변환하여 캐싱한다.
그렇다면 클래스 로더가 바이트 코드를 동적으로 로드한다는 것은 무슨 의미일까?
모든 클래스를 한 꺼번에 로드하는 것이 아닌, 런타임 시점에 필요한 클래스만 로드하는 것을 의미한다.
클래스 로드는 인스턴스를 생성 시, static 메서드나 변수를 사용할 때 static 변수에 값을 할당할 때 이루어진다. (동적 로드이기 때문에 메모리 효율적 사용 가능하다)
로딩은 클래스 로더가 .class 파일을 읽어 JVM 메모리에 로드하는 단계이다.
로드된 클래스는 Method Area에 저장된다.
링킹은 로드된 클래스가 실행될 수 있도록 준비하는 단계이다.
초기화는 static 변수를 사용자가 지정한 값으로 초기화하고 static 블록을 실행하는 단계이다.
실행 엔진이 바이트 코드를 기계어로 변환 시, 인터프리터와 JIT 컴파일러를 함께 사용하는 이유는 무엇인가
인터프리터는 바이트 코드를 한 줄씩 읽어서 실행하기에 초기 실행 속도 빠르다.
같은 코드 반복 시에도 계속 실행되므로 성능 저하 단점이 있다.
JVM은 인터프리터만 사용했다가, 이러한 단점을 해결하기 위해 JIT 컴파일러가 도입되었다.
JIT 컴파일러는 자주 실행되는 메서드를 네이티브 코드로 변환하여 캐싱한다.
변환 코드는 반복 실행 시 인터프리터보다 빠르게 실행된다.
JIT 컴파일 과정 자체에 시간이 소요되기 때문에 초기 실행 시 오버헤드 발생할 수 있다.
따라서 JVM은 두 방식을 동시 사용해서 실행 속도와 높은 반복 실행 성능 모두 추구한다.
| [매일메일] 멀티 쓰레딩에 대해서 설명해주세요 (0) | 2025.07.28 |
|---|---|
| [매일메일] 낙관적 락과 비관적 락에 대해 설명해 주세요. (0) | 2025.07.24 |
| [매일메일] JCF 자료구조의 초기 용량을 지정하면 좋은 점이 무엇인가요? (1) | 2025.07.21 |
| [매일메일] 멀티 태스킹 시스템의 한계에 대해서 설명해주세요 (0) | 2025.07.18 |
| [매일메일] Keep Alive에 대해 설명해 주세요. (0) | 2025.07.16 |