자바의 컴파일 과정
- 개발자가 자바 클래스 파일(.java) 작성
- 소스 파일을 자바 바이트 코드(.class 파일)로 컴파일
- JVM(자바 가상 머신) = 이해 가능
- 컴퓨터 = 아직 이해 불가
- 바이트 코드를 클래스 로더(Class Loader)에게 전달
- 클래스 로더는 동적 로딩(Dynamic Loading)을 담당하여 프로그램 실행 중 필요한 클래스 파일들을 로딩 및 링크하여 JVM 메모리(런타임 데이터 영역, Runtime Data Area)에 적재
- 클래스 로더(Class Loader) 세부 동작
- 로드 : 바이트 코드(클래스 파일)를 가져와서 JVM의 메모리에 로드
- 검증 : 클래스가 자바 언어 명세(Java Language Specification) 및 JVM 명세에 맞는 지 검사하여 안전한 코드만이 실행되도록 함
- 준비 : 클래스가 필요로 하는 메모리를 할당 (필드, 메서드, 인터페이스 등)
- 분석 : 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경
- 심볼릭 레퍼런스 : 클래스 파일 내 상수 풀(Constant Pool)에서 사용되는 참조 방식으로, 런타임 시점에 연결할 대상의 이름이나 위치만을 나타냄
- 다이렉트 레퍼런스 : 심볼릭 레퍼런스를 메모리에서 직접 접근할 수 있는 참조로 변환한 것
- 즉, MyClass라는 클래스 안에 myMethod() 라는 메서드가 있을 경우 클래스 파일 내 상수 풀에서는 MyClass.myMethod()로 접근할 수 있지만, JVM은 메모리 주소로만 접근 가능
- Ex) MyClass.myMethod() → 0xAAAFFF031와 같이 변경하는 과정
- 초기화 : 클래스 변수를 초기화하고 static 필드를 적절한 값으로 설정
- 실행 엔진(Excution Engine)은 JVM 메모리에 로드된 바이트 코드(클래스 파일)를 명령어 단위로 하나씩 실행
- 실행 엔진의 구성
- 인터프리터(Interpreter)
- 바이트 코드 명령어를 한 줄씩 읽고 실행
- 빠르게 시작할 수 있지만 전체적인 실행 속도는 느림
- JIT 컴파일러(Just-In-Time Compiler)
- 인터프리터의 단점을 보완하기 위해 도입
- 바이트 코드 전체를 컴파일하여 바이너리 코드(기계어)로 변경한 뒤 이후에는 바이너리 코드를 실행
- 이 과정에서 더 이상 인터프리팅할 필요가 없어 실행 속도가 빨라짐
- 인터프리터(Interpreter)
- 실행 엔진의 구성
인터프리터와 JIT 컴파일러 실행 시점
- 최초 실행
- 인터프리터만 사용
- JIT 컴파일러는 사용되지 않음
- 프로그램 실행 중
- 자주 호출되는 코드가 발견되면 JIT 컴파일러는 해당 코드를 네이티브 코드(기계어)로 변환
- 이 네이티브 코드(기계어)는 바이너리 형식(0과 1로 이루어진 이진코드)으로 저장되며, 이후 동일한 코드를 반복적으로 실행할 때는 이미 컴파일 된 네이티브 코드를 사용하여 훨씬 빠른 성능을 제공
- 네이티브 코드는 디스크가 아닌 JVM의 메모리 캐시(Code Cache)에 저장
- 즉, 최초 실행 시에는 인터프리터만을 사용하여 프로그램을 즉시 실행하고, 이후 프로그램 실행 중 JIT 컴파일러로 자주 호출되는 부분을 변환하여 실행 성능을 향상
모든 바이트 코드를 JIT 컴파일러로 저장하면 빠르지 않을까?
- JIT 컴파일러가 훨씬 빠르다면 '인터프리터를 사용하는 대신 JIT 컴파일러만 사용하면 되지 않을까?' 라는 의문이 생김
- JIT 컴파일러로 변환된 네이티브 코드는 JVM의 메모리 캐시(Code Cache)에 저장 됨
- Cache라는 것은 매우 빠른 속도를 갖지만 한정된 메모리이기 때문에 모든 바이트 코드를 네이티브 코드로 변환하여 메모리 캐시에 저장한다면 메모리 부족 문제가 발생할 수 있음
- 따라서, JIT 컴파일러는 '자주 사용되는 바이트코드'만을 메모리 캐시에 저장하는 것
'Language > Java' 카테고리의 다른 글
[JSP] 기본 문법 / 내장 객체 / 태그 (0) | 2024.12.02 |
---|---|
[GC] 가비지 컬렉터의 개념, 원리, 알고리즘 (1) | 2024.11.13 |
[JVM] JVM의 개념과 필요한 이유 (0) | 2024.11.13 |
[OOP] 객체지향 프로그래밍의 개념과 특징 (2) | 2024.11.11 |
Call by Value와 Call by Reference의 차이 (0) | 2024.09.10 |