JVM(Java Virtual Machine)은 자바 프로그램을 실행하는 가상 머신입니다. 자바 프로그래밍 언어는 컴파일된 바이트 코드를 JVM에서 실행되도록 디자인되어 있습니다. 이것은 자바 코드가 여러 플랫폼에서 동일한 방식으로 실행될 수 있도록 해줍니다.
JVM은 자바 프로그램의 실행 환경을 제공합니다. 이것은 메모리 관리, 스레드 관리, 예외 처리 등을 포함합니다. 또한 JVM은 자바 코드를 해석하고 컴파일하여 해당 플랫폼의 네이티브 코드로 변환합니다. 이것은 자바 프로그램이 다른 플랫폼에서 실행될 수 있도록 해주는 중요한 기능입니다.
JVM은 클래스 로더, JIT(Just-In-Time) 컴파일러, 가비지 컬렉터 등의 구성 요소로 구성됩니다. 클래스 로더는 자바 클래스 파일을 로드하여 메모리에 올리는 역할을 합니다. JIT 컴파일러는 실행 중에 자바 코드를 컴파일하여 최적화된 기계 코드를 생성합니다. 가비지 컬렉터는 더 이상 사용되지 않는 객체를 메모리에서 제거하여 자원을 해제하는 역할을 합니다.
JVM은 자바 프로그래밍 언어의 특징 중 하나로, 플랫폼에 독립적인 실행 환경을 제공하는 것입니다. 이것은 자바 프로그램이 다양한 플랫폼에서 실행될 수 있도록 해주며, 유지보수와 배포를 간편하게 해줍니다.

JVM 구성 요소
- Class Loader
- Runtime Data Area
- Execution Engine
- Java Native Interface
- Java Native Libraries
Class Loader
클래스 로더는 JVM이 자바 클래스 파일을 로드하여 런타임 환경에서 사용할 수 있는 자바 클래스로 변환하는 역할을 합니다.
클래스 로더는 자바 클래스 파일을 JVM의 메모리로 로드하는 역할을 합니다. 이 과정에서 클래스 로더는 다양한 소스에서 클래스를 로드할 수 있습니다. 예를 들어, 파일 시스템, 네트워크, JAR 파일 등에서 클래스를 로드할 수 있습니다. 클래스 로더는 로드된 클래스를 링크하고, 초기화하여 JVM의 메모리에 올리며, 이후에 클래스가 사용될 때 마다 필요한 경우 다시 로드하여 메모리에 올립니다.
클래스 로더는 보통 다음과 같이 세 가지 계층으로 구성됩니다.
- 부트스트랩 클래스 로더: JVM이 시작될 때 가장 먼저 로드되며, JDK의 기본 클래스들을 로드합니다. 부트스트랩 클래스 로더는 네이티브 코드로 구현되어 있습니다.
- 확장 클래스 로더: JVM이 시작될 때, 자동으로 로드되며, 시스템의 확장 기능을 제공하는 클래스들을 로드합니다.
- 시스템 클래스 로더: 애플리케이션에서 사용하는 클래스들을 로드합니다. 보통 애플리케이션 클래스 파일은 클래스 패스(Classpath)라고 불리는 특정 디렉토리나 JAR 파일에 위치해 있습니다.
클래스 로더는 자바 언어의 특성 중 하나인 동적 로딩(Dynamic Loading)을 지원하며, 런타임 환경에서 동적으로 클래스를 로드할 수 있습니다. 이것은 자바 언어가 유연하고 동적인 프로그래밍을 지원할 수 있도록 하는 중요한 기능 중 하나입니다.
※네이티브 코드(Native Code)
JVM이 실행하는 자바 프로그램을 해당 플랫폼에서 실행할 수 있는 기계어 코드를 말합니다.
Runtime Data Areas
JVM(Java Virtual Machine)은 자바 프로그램을 실행하기 위해 여러 가지 데이터 영역(Runtime Data Areas)을 제공합니다. 이러한 데이터 영역은 JVM이 실행되는 동안 사용되는 메모리 공간을 의미합니다. JVM의 데이터 영역은 다음과 같이 5개로 나누어집니다.
- Method Area: 모든 스레드에서 공유되는 영역으로, 클래스 정보, 상수, static 변수 등이 저장됩니다.
- Heap: 객체와 배열이 생성되는 영역으로, 동적으로 할당되는 메모리 공간입니다.
- Java Stack: 스레드마다 별도로 존재하며, 메서드 호출 시 지역 변수, 매개 변수, 임시 데이터 등이 저장되는 영역입니다.
- Native Method Stack: Java Stack과 유사하지만, native 메서드 호출 시 사용되는 영역입니다.
- PC Register: 현재 실행 중인 JVM 명령의 주소를 저장하는 영역입니다.
이러한 Runtime Data Areas는 JVM이 자바 프로그램을 실행하는 데 필요한 메모리 공간을 관리합니다. 각각의 영역은 특정한 용도로 사용되며, JVM은 이러한 영역들을 효율적으로 관리하여 자바 프로그램의 성능을 최적화합니다.
JVM은 이러한 Runtime Data Areas를 통해 자바 프로그램이 동작하는 데 필요한 메모리 공간을 제공하며, 자바 언어의 특성 중 하나인 가비지 컬렉션(Garbage Collection)을 지원합니다. 이러한 기능들은 자바 프로그래밍을 보다 안정적이고 효율적으로 만들어 줍니다.
Execution Engine
JVM(Java Virtual Machine)의 Execution Engine은 바이트 코드(Bytecode)를 실행하는 역할을 합니다. Execution Engine은 바이트 코드를 메모리 상에서 실행 가능한 기계어로 변환하고, 실행 결과를 JVM의 Runtime Data Areas에 반영합니다.
Execution Engine은 다음과 같은 두 가지 방식으로 바이트 코드를 실행합니다.
- Interpreter(해석기) 방식: 바이트 코드를 한 줄씩 읽어들이면서, 해당 바이트 코드에 대응하는 기계어를 실행합니다. 이 방식은 바이트 코드를 실시간으로 해석하기 때문에, JVM이 시작되는 속도가 빠르고, 메모리 사용량도 적지만, 실행 속도는 느립니다.
- Just-In-Time(JIT) 컴파일러 방식: 인터프리터 방식의 단점을 보완하기 위해 도입된 방식으로, 바이트 코드를 미리 기계어로 변환하고 캐시에 저장해 두는 방식입니다. 이 방식은 인터프리터 방식보다 빠른 실행 속도를 보장하지만, 변환된 코드를 캐시에 저장하기 때문에, JVM 시작 시 메모리 사용량이 증가하게 됩니다.
- Garbage Collection: Execution Engine은 JVM에서 바이트 코드를 실행하는 역할을 담당하며, 자바 프로그램이 동작하는 동안 메모리를 관리합니다. 가비지 컬렉션은 Execution Engine이 자동으로 수행하는 메모리 관리의 일환으로, 더 이상 사용되지 않는 객체를 JVM에서 자동으로 제거하여 메모리를 회수합니다. 가비지 컬렉션은 JVM에서 자동으로 수행되기 때문에, 개발자는 객체의 수명 주기를 관리할 필요가 없습니다. 따라서 개발자는 자바 프로그램의 로직 구현에 집중할 수 있으며, 가비지 컬렉션은 메모리 관리를 자동으로 처리해 줍니다.
Execution Engine은 바이트 코드를 실행하기 위해 자바 스택(Java Stack)과 네이티브 스택(Native Stack)을 사용합니다. Execution Engine은 JVM에서 바이트 코드를 실행하는 중요한 구성 요소 중 하나이며, JVM의 성능과 안정성에 매우 중요한 역할을 합니다.
Java Native Interface (JNI)
Java Native Interface(JNI)는 자바 프로그램에서 C, C++ 등의 다른 언어로 작성된 네이티브 코드(Native Code)를 호출하거나, 자바 코드를 C, C++ 등의 언어로 작성된 네이티브 코드에서 호출할 수 있게 해주는 프로그래밍 인터페이스입니다.
JNI를 사용하면, 자바 프로그램에서 네이티브 코드를 호출하여 하드웨어 제어나 성능 개선 등의 작업을 수행할 수 있습니다. 또한, 네이티브 코드에서 자바 객체를 생성하거나, 메서드를 호출하여 자바 프로그램에서 수행되는 작업을 제어할 수도 있습니다.
JNI는 Java Development Kit(JDK)의 일부로 제공되며, Java Native Interface Specification에 따라서 작성됩니다. JNI는 Java Virtual Machine과 네이티브 코드 간의 상호작용을 지원하므로, Java Native Interface를 사용하여 자바 프로그램과 다른 시스템 및 플랫폼 간에 상호작용을 할 수 있습니다.
JNI는 자바 프로그램에서 네이티브 코드를 사용하여 하드웨어 제어나 성능 개선 등의 작업을 수행할 수 있게 해주며, 자바 프로그램의 확장성과 유연성을 높여줍니다.
Native Method Libraries
Native Method Libraries는 자바에서 네이티브 코드를 사용하여 하드웨어 제어 등의 작업을 수행할 때, 해당 네이티브 코드를 포함하는 라이브러리를 의미합니다.
자바에서는 JNI(Java Native Interface)를 사용하여 네이티브 코드와 자바 코드 간의 상호작용을 지원하며, 이를 위해 네이티브 코드를 포함하는 라이브러리를 사용합니다. 이러한 네이티브 메서드 라이브러리는 자바 프로그램과 네이티브 코드 간의 인터페이스를 제공하며, 자바에서 네이티브 코드를 호출하거나, 네이티브 코드에서 자바 객체를 생성하거나, 메서드를 호출할 수 있게 해줍니다.
네이티브 메서드 라이브러리는 일반적으로 C, C++ 등의 언어로 작성되며, 라이브러리 파일(.so, .dll 등)로 제공됩니다. 자바에서 네이티브 메서드 라이브러리를 사용하기 위해서는 JNI를 사용하여 해당 라이브러리를 로드하고, 해당 라이브러리에서 제공하는 네이티브 메서드를 호출해야 합니다.
이러한 네이티브 메서드 라이브러리는 하드웨어 제어, 성능 개선 등의 작업을 수행할 때 자바 프로그램의 확장성과 유연성을 높여줍니다. 또한, JNI를 사용하여 네이티브 메서드 라이브러리를 호출하는 것은 어렵지 않으며, 다양한 플랫폼에서 동작할 수 있도록 지원됩니다.
'Java' 카테고리의 다른 글
| All about JAVA (0) | 2024.04.08 |
|---|---|
| Class Loader (0) | 2024.04.08 |
| Dynamic Proxy Classes (0) | 2024.04.08 |
| Reflection (0) | 2024.04.08 |
| 자바 클래스 파일(feat. compiler) (0) | 2024.04.08 |