늦은 프로그래밍 이야기
JVM 구조 본문
JVM (Java Virtual Machine)
- Java는 OS에 종속적이지 않다는 특징을 가지고 있다.
- OS에 종속받지 않고 실행되기 위해서는 OS 위에서 Java를 실행시킬 JVM이 필요.
- 즉, OS에 종속받지 않고 CPU가 Java를 인식, 실행할 수 있게 하는 가상 컴퓨터.

JDK (Java Development Kit)
- Java를 사용하기 위해 필요한 모든 기능을 갖춘 Java용 SDK(Software Development Kit)이다.
- JDK는 JRE를 포함하고 있다.
- 컴파일러(JavaC), jdb, JavaDoc과 같은 도구도 포함.

JRE (Java Runtime Environment)
- JVM과 자바 클래스 라이브러리(Java Class Library) 등으로 구성되어 있다.
- 컴파일 된 Java 프로그램을 실행하는데 필요한 패키지.
JVM 구조


- JVM은 크게 아래와 같이 구성되어 있다.
- 클래스 로더 (Class Loader)
- 런타임 데이터 영역 (Runtime Data Area)
- 실행 엔진 (Execution Engine)
- 인터프리터 (Interpreter)
- JIT(Just In Time) 컴파일러
- 가비지 콜렉트 (Grabage Collector)
- JNI (Java Native Interface)
- 네이티브 메소드 라이브러리
클래스 로더 (Class Loader)

- JVM 내로 클래스 파일(.class)을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈.
- 런타임 시 동적으로 클래스를 로드하고 Jar 파일 내 저장된 클래스들을 JVM 위에 탑재한다.
- 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크하는 역할.
Loading
- BootStrap ClassLoader : 부트스트랩 클래스 경로에서 rt.jar만 로드하는 클래스를 담당.
- Extension ClassLoader : ext 폴더(jre\lib) 내부에 있는 클래스 로드를 담당.
- Application ClassLoader : Application Level Classpath, 경로 언급 환경 변수(Path Mentioned Environment Viarable) 등을 로드하는 역할.
Linking
- 확인 (Verify) : 생성된 바이트코드가 적절한지 여부를 확인. 실패시 확인 오류가 발생.
- 준비 (Prepare) : 모든 정적 변수(static variable)에 대해 메모리가 기본값으로 할당.
- 해결 (Resolve) : 모든 기호 메모리(symbolic memory) 참조는 메소드 영역(Method Area)의 원래 참조로 대체.
Initialization
- Class Loding의 마지막 단계.
- 모든 정적 변수(static variable)는 원래 값으로 할당되고 정적(static) 블록이 실행된다.
메모리 영역 (Runtime Data Area)
- 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간

PC Resister
- Thread가 시작될 때 생성되는 공간으로, 스레드마다 하나씩 존재한다.
- 명령이 실행되면 현재 실행중인 명령의 주소를 보유하고 다음 명령으로 업데이트 된다.
Native Method Stack
- 컴파일되어 생성되는 바이트 코드가 아닌 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역.
- JNI를 통해 바이트 코드로 전환하여 저장.


Method Area (스태틱 영역, 클래스 영역)
- 정적(static) 변수를 포함하여 모든 클래스 수준 데이터를 저장.
- JVM당 하나만 있으며 공유 자원이다.
Heap Area
- 모든 객체와 new 연산자로 생성되는 인스턴스 변수 및 배열 데이터를 저장.
- Method Area에 올라온 클래스들만 인스턴스로 생성할 수 있다.
- JVM당 하나만 있으며 공유 자원이다.
- Garbage Collector가 참조되지 않는 메모리를 확인하고 제거.
Stack Area (스레드 영역)
- 모든 스레드에 별도의 공간이 생성. (thread-safe)
- 각종 형태의 변수, 메소드의 정보를 저장한다.
- 메소드 호출 시마다 각각의 스택 프레임이 생성되고 메소드 수행이 끝나면 프레임별로 삭제.
예시 (main 메소드)



- JRE는 main 메소드가 있는지 먼저 찾는다.
- main 메소드 존재 == true -> JVM 부팅
- JVM은 바이트파일(.class)을 실행하고 작성한 클래스와 import package를 데이터 저장영역의 Method Area에 올린다.
- 데이터 저장 영역의 Stack 영역에 main() 스택 프레임이 올라간다.
실행 엔진 (Execution Engine)
인터프리터 (Interpreter)
- 바이트코드를 더 빠르게 해석하지만 실행 속도가 느리다.
- 하나의 메소드를 여러번 호출할 때마다 새로운 해석이 필요하다.
JIT 컴파일러 (Just In Time)
- 바이트 코드를 변환할 때 인터프리터를 사용하다가,
- 반복되는 코드를 발견하면 전체 바이트코드를 컴파일하고 네이티브 코드로 변경.
- 네이티브 코드를 반복되는 메소드 호출에 사용하여 시스템 성능을 향상시킨다.
Garbage Collector
더이상 참조되지 않는 인스턴스를 찾아 메모리에서 삭제.
'내일배움캠프 > Java 심화' 카테고리의 다른 글
| Thread (0) | 2022.12.02 |
|---|---|
| 추상클래스 vs 인터페이스 (0) | 2022.12.01 |
| Mutable, Immutable (0) | 2022.12.01 |
| Wrapper 클래스 (0) | 2022.11.30 |
| 필드, 메소드의 구분 / Block / Scope (0) | 2022.11.30 |