728x90
1. JVM 이란?
Java Virtual Machine 으로 Java 라는 언어가 플랫폼에 자유롭게 실행될 수 있는 근간이다.
Write once, run anywhere
우리가 .java 형식으로 작성한 파일들은 Java Compiler 를 통해 바이트 코드로 변환된다.
그리고 JVM 은 이 바이트 코드를 읽어내고 실제 실행시키는 역할을 한다.
그림과 같이 JVM 은 크게 Class Loader, Excution, Runtime Data Area 로 나눌 수 있다.
인터넷에서는 GC 까지 4 가지로 나누는 것도 있지만 GC 는 Excution 에 포함된다고 보는 것이 맞다 생각한다.
(1) Class Loader
Class Loader 는 동적 로딩을 통해 필요한 클래스들을 로딩 및 링크하여 메모리 영역에 올리는 역할을 한다.
클래스를 메모리에 올리는 로딩 기능은 모든 클래스를 한 번에 올리지 않고 어플리케이션에서 필요한 경우에 동적으로 메모리에 적재하게 된다.
각 단계를 다시 세분화할 수 있다.
- Loading
- Bootstrap Class Loader
- JVM 시작 시 가장 처음 실행되는 클래스 로더이다.
- 해당 로더는 Java 클래스를 로드하는 것이 아니라 Java 클래스를 로드할 수 있도록 하는 Java 자체의 클래스 로더와 최소한의 기본 Java 클래스들을 로드한다.
- Java 9 이후에서는 /lib 내에 모듈화 된 최상위 클래스들만 로드한다.
- Extension Class Loader
- 확장 클래스 로더는 Bootstrap Class Loader 의 자식으로, 확장 자바 클래스들을 로드한다.
- java.ext.dirs 환경 변수에 설정된 디렉토리 클래스 파일을 로드하고, default 로 ${JAVA_HOME}/jre/lib/ext 클래스 파일을 로드한다.
- Java 9 이후 Platform Loader 로 변경되었으며, BuiltinClassLoader 를 상속한다.
- Application Class Loader
- 자바 프로그램 실행 시 지정한 ClassPath 에 있는 클래스 파일 혹은 jar 에 속한 클래스들을 로드한다.
- 개발자가 직접 생성한 .class 파일을 모두 로드한다고 보면 된다.
- 이를 System Class Loader 라 부르기도 한다.
- 일반적으로 대부분의 클래스들이 여기에 존재한다.
- Bootstrap Class Loader
- Linking
- Verify
- Class Loader 를 사용해 읽어들인 클래스가 Java 언어 및 JVM 명세에 부합하는 지 확인한다.
- .class 파일이 유효한 지 확인하는 단계이다.
- Prepare
- Class 가 필요로하는 메모리를 할당하고 정의된 필드나 메서드를 나타내는 데이터 구조를 준비한다.
- 클래스 변수와 기본 값에 대해 필요한 메모리를 준비하는 과정이다.
- Resolve
- 심볼릭 메모리 레퍼런스를 실제 메소드 영역에 있는 레퍼런스들로 교체한다.
- ExampleClass ex = new ExampleClass();
- 여기서 ex 를 실제 인스턴스와 매핑시켜주는 역할을 한다.
- Verify
- Initialization
- Initialize
- Linking 의 prepare 단계에서 확보한 메모리 영역에 클래스의 static 값들을 할당한다.
- Initialize
클래스 로더의 동작 방식
- JVM 의 메소드 영역에 클래스가 로드되어있는 지 확인한다. 로드되어있다면 해당 클래스를 사용한다.
- 메소드 영역에 클래스가 없는 경우, 시스템 클래스 로더에 클래스 로드를 요청한다.
- 시스템 클래스 로더 -> 확장 클래스 로더 -> 부트스트랩 클래스 로더 로 요청을 위임한다.
- 부트스트랩 클래스 로더는 부트스트랩 Classpath(JDK, JRE, LIB) 에 해당 클래스를 찾고 없으면 확장 클래스 로더로 요청을 넘긴다.
- 확장 클래스 로더는 확장 Classpath( + EXT) 에서 해당 클래스를 찾고 없으면 시스템 클래스 로더에게 요청을 넘긴다.
- 시스템 클래스 로더는 시스템 Classpath 에서 해당 클래스를 찾고 없으면 ClassNotFoundException 을 발생시킨다.
(2) Excution
Excution 은 실행 엔진(Excution Engine) 으로 불린다. 실행 엔진은 바이트 코드를 실제 읽어 동작시키게 하는 역할을 맡고 있다. 하지만 바이트 코드도 기계어는 아니기 때문에 JVM 내부에서 실행할 수 있는 기계어로 변환하는 과정이 필요하다.
실행 엔진 역시 3가지로 구성되어있다.
- Interpreter
- 바이트 코드를 한 줄씩 해석해서 실행한다.
- JVM 에서는 기본적으로 인터프리터 방식으로 동작하고, 매번 해석해야하기에 속도가 느리다.
- JIT Compiler
- Just In-Time 컴파일러이다.
- 인터프리터의 단점을 보완하기 위해 반복되는 코드를 발견하면 바이트 코드 전체를 컴파일하여 Native Code 로 변경하고 캐싱하는 역할을 한다.
- 컴파일된 Native Code 를 실행하기에 실행 속도는 인터프리터보다 빠르다.
- 이름 그대로 자신이 가지고 있는 코드를 즉시 실행한다.
- Garbage Collector
- Java 에서는 JVM 안에 GC 가 존재하기에 메모리 누수를 "덜" 신경써도 된다.
- GC 는 Heap 메모리 영역에서 더 이상 사용되지 않는 메모리들을 회수해준다.
- 더 자세한 내용은 GC 에 대한 게시글을 확인하자.
- https://happyzodiac.tistory.com/21
(3) Runtime Data Area
실제 데이터들이 저장되는 영역이다. 개발자가 직접 신경써야할 유일한 영역이라고 할 수 있다.
역시 5가지 영역으로 나눠진다. 큰 그림은 흔히 보던 컴퓨터 메모리 구조와 비슷하다.
- Method Area
- Class Loader 에게 요청한 데이터들이 저장되는 공간이다.
- JVM 이 시작될 때 생성되는 공간으로 바이트 코드를 메모리 공간에 올릴 때 초기화되는 대상(Static)을 저장하기 위한 공간이다.
- 클래스들에 대한 정보도 존재하기에 인스턴스를 생성하기 위해서는 해당 영역을 참조해야하며, 모든 스레드가 이 영역을 공유한다.
- Metadata 는 5가지 정도로 분류할 수 있다.
- Runtime Constant Pool
- Method Area 영역이지만 독자적으로 중요성을 띈다.
- Type 의 상수 정보를 저장하는 Pool 이다.
- JVM 은 해당 데이터를 통해 메서드나 필드의 실제 메모리 상 주소를 찾아 참조한다.
- Type Infomation : 클래스와 인터페이스 정보를 나타낸다.
- Field Infomation : 인스턴스 변수의 정보를 저장한다.
- Method Information : 메소드의 모든 정보를 저장한다.
- Class Variable : static 으로 선언된 변수들을 저장한다.
- Runtime Constant Pool
- 정리하자면 메소드 영역에는 정적 필드와 클래스 구조만을 갖고 있다.
- Heap
- 인스턴스 객체들이 저장되는 공간이다.
- new 연산자로 생성되는 객체들이라 생각하면 편하다.
- 이외에도 Reference Type 이 저장된다.
- GC 의 대상으로 GC 가 관리하는 메모리 공간이다.
- Heap 영역까지 스레드들이 함께 공유한다.
- Stack
- 메서드를 실행하면서 임시적으로 사용되는 변수나 정보들이 저장되는 공간이다.
- Stack 구조이며 컴퓨터 메모리에서 사용되는 용도와 같다.
- Heap 과 Stack 은 메모리 공간에서 유동적으로 사용되며 메모리가 가득 차게 되면 StackOverflow 가 발생한다.
- PC Register
- 현재 수행중인 JVM 명령어 주소를 저장하는 공간이다.
- Native Method Stack
- Java 가 아닌 Native 언어가 실행되는 공간이다.
- 이외에도 Native Method Library, Native Method Interface 등이 있지만 JVM 의 주요 구성 요소는 아니므로 넘어가겠다.!
728x90
'Programming > JAVA' 카테고리의 다른 글
[Java] Volatile? Synchronized? Concurrent? 자바의 동기화 방식 (4) | 2024.11.09 |
---|---|
[JAVA] 정적 파일 위치 설정 및 src/main/resource 경로 ClassLoader 로 읽기 및 Java Reflection 살펴보기 (0) | 2024.07.11 |
[JAVA] Spring 없이 웹 서버 구축! (4) 라우팅을 위한 Mapper (0) | 2024.07.09 |
[JAVA] Spring 없이 웹 서버 구축! (3) HTTP Request, Response 객체 (0) | 2024.07.09 |
[Java] String 과 Byte[] 의 차이 by 인코딩! 바이트 파일을 String 으로 읽으면? (1) | 2024.07.05 |