반응형
JVM(Java Virtual Machine)이란?
JVM의 정의와 특징
JVM은 Java 바이트코드를 실행하는 가상 컴퓨팅 엔진이다.
주요 특징은 다음과 같다.
- ⭐️ 플랫폼 독립성 : 다양한 OS에서 자바 프로그램을 실행할 수 있음.
- 메모리 관리 : 가비지 컬렉션을 통한 자동 메모리 관리.
- 바이트코드 실행 : 컴파일된 바이트코드를 기계어로 변환하여 실행.
JVM의 구조
아래의 이미지는 JVM의 구조이다. 크게 Class Loader, Runtime Data Area, Execution Engine으로 나눌 수 있다.
- 클래스 로더(Class Loader): 자바 클래스를 로드하고 링크하여 런타임 데이터 영역에 배치.
- Bootstrap Class Loader: JVM이 시작될 때 가장 먼저 로드되는 클래스 로더로, JDK의 핵심 클래스 라이브러리(JRE/lib/rt.jar)를 로드.
- Extension Class Loader: 확장 클래스 라이브러리를 로드(JRE/lib/ext 디렉터리).
- Application Class Loader: 응용 프로그램의 클래스 경로에 있는 클래스를 로드(classpath)
- 런타임 데이터 영역(Runtime Data Area)
- 메서드 영역(Method Area): 클래스 구조와 메서드 코드를 저장.
- 힙 영역(Heap Area): 객체와 인스턴스 변수를 저장.
- 스택 영역(Stack Area): 지역변수와 부분 결과를 저장.
- PC 레지스터(PC Register): 현재 실행중인 명령의 주소를 저장
- 네이티브 메서드 스택(Native Method Stack): 네이티브 코드 실행에 사용.
- 실행 엔진 (Execution): 인터프리터와 JIT 컴파일러를 사용하여 바이트코드를 실행.
- 인터프리터(Interpreter): 바이트 코드를 한 줄씩 읽어 해석하고 실행. 초기 실행 시 빠르지만, 반복적인 작업에서는 비효율적일 수 있음.
- JIT 컴파일러(JIT Compielr): 실행 중인 바이트 코드를 기계어로 변환하여 성능을 향상시킴. JIT 컴파일러는 자주 실행되는 코드를 캐시에 저장하여 이후 실행 속도를 높임.
- C1 컴파일러: 빠른 컴파일을 목표로 하며, 간단한 최적화를 수행.
- C2 컴파일러: 고급 최적화를 수행하여 실행 성능을 크게 향상시킴.
- 가비지 컬렉터(Garbage Collector): 더 이상 사용되지 않는 객체의 메모리를 자동으로 해제.
Interpreter | JIT(Just In Time) 컴파일러 | |
특징 | 바이트 코드를 한 줄씩 읽고 실행. 즉시 실행 가능 -> 프로그램 시작 시 딜레이가 적음. 디버깅이 용이하고 초기 오버헤드가 낮음. |
자주 실행되는 바이트 코드 전체를 네이티브 머신 코드로 컴파일하여 성능 향상. 실행 중 코드 실행 패턴을 분석하고 런타임 정보를 활용하여 최적화를 수행. 프로그램이 실행되는 동안 필요한 부분만 컴파일 하므로 전체 프로그램을 처음부터 컴파일할 필요 없음 |
단점 | ❗️ 반복적 연산이 많은 경우 반복적으로 바이트 코드를 해석해야 하므로 런타임 오버헤드가 발생할 수 있으며, 한 줄씩 해석하기 때문에 성능이 떨어질 수 있음 | ❗️ 초기 오버헤드가 발생할 수 있고, 변환 코드를 저장하기 위한 추가 메모리 필요. |
Java 컴파일 과정
- 소스 코드 작성
- 개발자가 .java 확장자를 가진 자바 소스 코드 파일을 작성.
- 컴파일
- 자바 컴파일러(javac)가 소스 코드(.java)를 읽어 바이트코드(.class)로 변환 시도.
- 바이트코드 생성
- 컴파일이 성공하면 .class 확장자를 가진 바이트 코드 파일이 생성.
- 이 바이트 코드는 컴퓨터에서 직접 실행 불가. JVM만 이해하는 중간 코드임.
- 컴파일된 바이트코드(.class)는 JVM의 클래스 로더에 전달.
- 클래스 로더 동작
- 클래스 로더는 .class 파일을 JVM 메모리에 로드함.
- 그 외에도 검증, 준비, 분석, 초기화 과정을 거침.
- 검증: 자바 언어 명세 및 JVM 명세에 맞게 구성되었는지 검사.
- 준비: 클래스가 필요로 하는 메모리를 할당.
- 분석: java/lang/String 형태의 심볼릭 레퍼런스를 0x5f3759df(메모리 주소) 형태의 다이렉트 레퍼런스로 변경.
- 초기화: 클래스 변수들을 적절한 값으로 초기화.
- 동적 로딩을 통해 필요한 클래스들을 로딩 및 링크하여 Runtime Data Area에 배치.
- 실행
- JVM의 실행 엔진(Execution Engine)이 메모리에 로드된 바이트코드를 실행.
- 초기에는 인터프리터 방식으로 바이트 코드를 실행.
- 이후, 프로그램이 '워밍업'되면서 자주 실행되는 코드(핫스팟)를 JIT컴파일러로 컴파일함.
728x90
반응형
'Language > Java' 카테고리의 다른 글
Promotion(자동형변환)과 Casting(명시적형변환), Upcasting vs Downcasting (0) | 2024.12.05 |
---|---|
String Interning (0) | 2024.12.04 |
String vs String Builder vs String Buffer (0) | 2024.12.03 |
Stream API (0) | 2024.12.02 |
Java는 Call by Reference가 존재하지 않는다. (0) | 2024.12.01 |