Java Virtual Machine
자바를 실행하기 위한 가상 기계(컴퓨터)
JVM은 Java프로그램이 플랫폼에 독립적으로 실행될 수 있게 = OS에 종속적이지 않게 해준다
Java 소스코드(원시코드(*.java))는 CPU가 인식을 하지 못하므로 기계어로 컴파일을 해줘야 한다
Java는 이 JVM 이라는 가상머신을 거쳐서 OS에 도달하기 때문에 OS가 인식할 수 있는 기계어로 바로 컴파일 되는게 아니라 JVM이 인식할 수 있는 Java bytecode(*.class)로 변환된다
JVM의 주요 기능
바이트코드 실행
Java 프로그램은 먼저 Java 컴파일러(javac)에 의해 바이트코드(.class 파일)로 컴파일된다
이 바이트코드는 JVM이 이해할 수 있는 명령어 집합으로 변환된다
메모리 관리
JVM은 프로그램 실행 중 필요한 메모리를 관리한다
여기에는 힙(heap), 스택(stack), 메소드 영역(method area), 네이티브 메소드 스택 등이 포함된다
가비지 컬렉션
JVM은 사용되지 않는 객체를 자동으로 메모리에서 해제하는 가비지 컬렉션(Garbage Collection) 기능을 제공한다
이는 메모리 누수를 방지하고 메모리 효율성을 높인다
플랫폼 독립성 = OS 독립성
JVM은 다양한 운영 체제와 하드웨어에서 동일하게 동작한다
즉, 한번 작성된 Java 프로그램은 어디서든 실행될 수 있다
JVM의 구조
JVM은 크게 다음과 같은 구성 요소로 이루어져 있다
클래스 로더 시스템(Class Loader System)
상위 클래스 로더가 먼저 클래스르 ㄹ로드하고, 필요한 경우에만 하위 클래스 로더가 클래스를 로드한다
Bootstrap Class Loader: JVM이 시작될 때 기본 클래스(JDK 클래스)를 JVM의 메모리로 로드한다
Extension Class Loader: 확장 클래스를 로드한다
Application Class Loader: 사용자 애플리케이션 클래스를 로드한다
확장 클래스 Java 표준 라이브러리의 기능을 확장하고, 추가적인 표준 API를 제공 하기 위해 JVM이 제공하는 기능을 위해 로드되는 클래스이다 이러한 클래스들은 주로 Java 확장 패키지에 속하며, 표준 Java 라이브러리 외에도 추가적인 기능을 제공한다
위치 : JVM 확장 디렉토리 (JAVA_HOME/lib/ext 또는 시스템 지정 디렉토리)에 위치.
사용자 애플리케이션 클래스 사용자 애플리케이션 클래스는 사용자가 작성한 애플리케이션 코드를 포함하는 클래스이다 이 클래스들은 주로 애플리케이션의 비즈니스 로직을 담당하며, 개발자가 직접 작성하거나 외부 라이브러리로부터 가져온 클래스들을 포함한다 위치 : 애플리케이션의 클래스패스에 위치. 프로젝트 디렉토리 또는 외부 jar 파일들.
실행 엔진(Execution Engine)
인터프리터(Interpreter): 바이트코드를 하나씩 읽어 해석하고 실행한다
JIT 컴파일러(Just-In-Time Compiler): 자주 사용되는 바이트코드를 기계어로 변환하여 실행 성능을 향상시킨다
가비지 컬렉터(Garbage Collector): 불필요한 객체를 메모리에서 해제한다
JIT 컴파일러(Just-In-Time Compiler) JIT 컴파일러는 JVM의 실행 엔진의 일부로, 프로그램이 실행되는 동안 바이트코드를 기계어로 컴파일한다. 이를 통해 인터프리터 방식보다 더 빠른 실행 속도를 얻을 수 있다.
JIT 컴파일러(Just-In-Time Compiler)의 역할 동적 컴파일: 프로그램 실행 중에 자주 사용되는 메소드나 루프와 같은 바이트코드 조각을 기계어로 컴파일하여 성능을 향상시킨다 성능 최적화: 실행 중에 수집된 프로파일링 정보를 바탕으로 최적화된 기계어 코드를 생성한다 캐싱: 한번 컴파일된 기계어 코드는 캐시에 저장되어, 동일한 바이트코드가 다시 실행될 때 컴파일 과정을 생략하고 바로 실행할 수 있게 한다
JIT 컴파일러의 장점 성능 향상: JIT 컴파일러는 자주 실행되는 코드 블록을 기계어로 변환하여 실행 속도를 크게 향상시킨다 동적 최적화: 프로그램 실행 중 수집된 데이터를 바탕으로 최적화된 코드를 생성할 수 있어, 정적 컴파일러보다 효율적이다 메모리 효율성: 필요한 코드만 선택적으로 컴파일하므로 메모리를 효율적으로 사용할 수 있다
메모리 영역(Memory Area)
메소드 영역(Method Area): 클래스, 메소드 정보 등을 저장한다
힙 영역(Heap Area): 객체가 생성되고 관리된다
스택 영역(Stack Area): 각 스레드의 호출 스택이 저장된다
PC 레지스터(PC Register): 현재 실행 중인 명령의 주소를 저장한다
네이티브 메소드 스택(Native Method Stack): 네이티브 메소드(C나 C++로 작성된 메소드)의 실행에 사용된다
JVM의 작동 방식
클래스 로딩: JVM은 프로그램이 실행되면 필요한 클래스를 로딩한다. 클래스 로더는 클래스 파일을 찾고 메모리에 로드한다
바이트코드 검증: 로드된 바이트코드는 JVM이 안전하게 실행할 수 있도록 검증된다
실행: 실행 엔진이 바이트코드를 인터프리트하거나 JIT 컴파일러를 사용하여 기계어로 변환해 실행한다
가비지 컬렉션: 실행 중 필요 없어진 객체를 가비지 컬렉터가 자동으로 해제한다
JVM은 이러한 구성 요소와 기능을 통해 Java 프로그램이 다양한 환경에서 안정적이고 효율적으로 실행될 수 있게 한다
'TIL(Develop)' 카테고리의 다른 글
오버라이딩과 오버로딩 차이 (0) | 2024.05.23 |
---|---|
멀티스레드와 스레드 풀 / 스레드와 프로세스의 차이 (0) | 2024.05.17 |
Java의 메모리 관리와 가비지 컬렉션 (0) | 2024.05.16 |
Java 접근제어자 (0) | 2024.05.15 |
Java에서 동일성과 동등성의 차이 (1) | 2024.05.15 |