본문 바로가기

CS Study

8월 4주차 JDK, JRE, JVM

 

 


공통 질문

1. JAR, WAR

2. JDK > JRE > JVM

  • Bytecode
  • javac Compiler
  • JIT Compiler

3. GC


Flow

 java 언어 ----> javac Compiler ----> Bytecode(.class) --> jar, war 패키징
Bytecode ----> 인터프리터, JIT Compiler ----> 현지 언어(해당 컴퓨터의 기계어)

 

 

 

https://youtu.be/OxvtGYvVkRU?si=8PTWLqwmdGJCHoaw%EF%BB%BF
https://youtu.be/OxvtGYvVkRU?si=8PTWLqwmdGJCHoaw%EF%BB%BF

 

java 코드를 실행 할 컴퓨터의 종류에 따라 따로 따로 컴파일을 해야 했었다.

그러나 JVM을 OS 별로 설치하면서 java는 os에 독립적이게 되었다.

 

 

Bytecode

  • .class 파일: Java 컴파일러가 생성한 Bytecode 파일, 개별 클래스 단위로 존재.
  • JAR 파일: 여러 .class 파일과 리소스를 하나로 묶어 배포하기 위한 압축 파일.
  • WAR 파일: 웹 애플리케이션을 배포하기 위한 압축 파일로, 웹 애플리케이션의 모든 구성 요소를 포함.

.class 파일이 Java 애플리케이션의 개별적인 구성 요소라면, JAR와 WAR 파일은 이들을 모아 패키징한 형태라고 볼 수 있습니다

 

 

java -> Bytecode 과정

1. Java 소스 코드 작성

  • 개발자가 Java 프로그래밍 언어로 .java 파일을 작성합니다.
  • 이 소스 파일은 인간이 읽을 수 있는 텍스트 형식으로, 클래스, 메서드, 변수 등을 정의합니다.

2. Java 컴파일러(Javac) 사용

  • Java 소스 코드를 Bytecode로 변환하기 위해 javac라는 Java 컴파일러를 사용합니다.
javac YourClass.java

 

  • 이 명령어를 실행하면 YourClass.class라는 파일이 생성됩니다.

3. 구문 분석 (Parsing)

  • 컴파일러는 소스 코드를 읽어 들이고, 구문 분석(Parser)을 통해 코드의 구조를 분석합니다.
  • 이 과정에서 소스 코드는 토큰화(Tokenization)되며, 컴파일러는 이 토큰을 바탕으로 코드의 문법을 확인하고, 추상 구문 트리(Abstract Syntax Tree, AST)를 생성합니다.

4. AST 변환 및 최적화

  • 추상 구문 트리(AST)는 소스 코드의 논리적 구조를 나타내며, 컴파일러는 이를 통해 코드의 흐름과 구조를 이해합니다.
  • 컴파일러는 AST를 바탕으로 코드의 최적화를 수행합니다. 이 과정에서는 불필요한 코드 제거, 상수 폴딩(Constant Folding), 루프 최적화 등 여러 최적화 기법이 적용될 수 있습니다.

5. Bytecode 생성

  • 최적화된 AST를 바탕으로 컴파일러는 Java 바이트코드를 생성합니다.
  • 바이트코드는 JVM에서 실행될 수 있는 저수준의 명령어로 구성된 코드입니다. 이 명령어들은 JVM의 스택 기반 가상 머신에서 실행될 수 있도록 설계되어 있습니다.
  • 이 과정에서, 컴파일러는 Java 언어의 고수준 구조(클래스, 메서드, 필드 등)를 Bytecode 명령어로 변환합니다.

6. 클래스 파일 생성

  • 생성된 Bytecode는 .class 파일에 저장됩니다. 이 파일은 각 클래스에 대해 하나씩 생성되며, 컴파일된 Bytecode를 포함합니다.
  • .class 파일에는 클래스 정의, 메서드, 필드, 상수 풀(Constant Pool) 등 클래스에 대한 모든 정보가 포함되어 있습니다.

7. 바이트코드 실행

  • 생성된 Bytecode는 JVM에 의해 해석되거나 JIT(Just-In-Time) 컴파일러에 의해 네이티브 코드로 컴파일되어 실행됩니다.
  • JVM은 클래스 로더를 통해 .class 파일을 메모리에 로드하고, 이를 실행합니다. JVM은 Bytecode를 해석하면서 프로그램의 로직을 수행합니다.

 


 

 

 

Compiled & Interpreted

 

그림 출처:

https://youtu.be/OxvtGYvVkRU?si=8PTWLqwmdGJCHoaw%EF%BB%BF




 

JIT 컴파일러

JIT (Just-In-Time) 컴파일러는 런타임 시 바이트 코드를 원시 시스템 코드로 컴파일하여 Java 애플리케이션의 성능을 향상시키는 런타임 환경의 컴포넌트입니다.

JIT 컴파일러 역할

Java 프로그램이 실행될 때, JVM은 먼저 바이트코드를 해석해 한 줄씩 실행합니다.

그러나 이 방식은 반복적으로 실행되는 코드에 대해 비효율적일 수 있습니다.

JIT 컴파일러는 성능을 높이기 위해 자주 실행되는 "핫스팟(Hotspot)" 코드 영역을

네이티브 코드로 변환하여 더 빠르게 실행할 수 있게 합니다.

JIT 컴파일러 작동 과정

  1. JVM 초기화 및 클래스 로딩
    • Java 애플리케이션이 실행되면 JVM은 .class 파일을 로드하여 메모리에 올립니다.
    • 초기에는 JVM이 바이트코드를 해석해 한 줄씩 실행하며 프로그램을 시작합니다.
  2. 프로파일링 (Profiling)
    • JVM은 실행 중인 코드의 성능을 모니터링합니다.
    • 자주 실행되거나 반복적으로 호출되는 메서드와 루프와 같은 "핫스팟" 영역을 식별합니다.
    • 이 과정에서 각 메서드와 코드 블록이 얼마나 자주 실행되는지를 추적합니다.
  3. JIT 컴파일 결정
    • 특정 코드가 일정 횟수 이상 실행되거나 자주 호출되면, JVM은 해당 코드를 JIT 컴파일러에 넘겨 네이티브 코드로 컴파일할 것을 결정합니다.
    • 이 시점에서 JIT 컴파일러가 활성화됩니다.
  4. 바이트코드 최적화
    • JIT 컴파일러는 바이트코드를 네이티브 코드로 변환하기 전에 최적화 작업을 수행합니다.
    • 예를 들어, 인라인 함수(함수 호출 대신 함수 내용을 직접 삽입), 루프 최적화, 불필요한 연산 제거 등의 최적화 기법을 적용하여 성능을 극대화합니다.
  5. 네이티브 코드 생성
    • JIT 컴파일러는 최적화된 바이트코드를 네이티브 코드로 변환합니다.
    • 이 네이티브 코드는 특정 CPU 아키텍처에서 직접 실행될 수 있는 기계어로 구성됩니다.
    • 변환된 네이티브 코드는 메모리에 캐싱되며, 이후에는 해석되지 않고 네이티브 코드로 직접 실행됩니다.
  6. 네이티브 코드 실행
    • JVM은 네이티브 코드로 변환된 해당 코드를 실행합니다.
    • 이로 인해 해석(interpretation)보다 훨씬 빠른 속도로 코드가 실행됩니다.
    • 이후 동일한 코드가 재실행될 때마다 JVM은 이미 생성된 네이티브 코드를 사용하여 성능을 최적화합니다.
  7. 캐싱 및 실행 유지
    • JIT 컴파일러가 생성한 네이티브 코드는 JVM의 런타임 환경에서 캐싱됩니다.
    • JVM은 필요에 따라 추가적인 최적화를 수행할 수도 있으며, 런타임 상황에 따라 다시 컴파일할 수도 있습니다.

JIT 컴파일의 이점

  • 성능 향상: 해석 방식보다 훨씬 빠른 속도로 코드가 실행됩니다.
  • 동적 최적화: 실행 중인 애플리케이션의 상태에 따라 최적화를 적용할 수 있습니다.
  • 메모리 효율성: 초기에는 해석을 통해 메모리를 효율적으로 사용하고, 필요에 따라 네이티브 코드를 생성합니다.

JIT 컴파일의 한계

  • 초기 성능 저하: JIT 컴파일이 수행되는 동안 초기 실행 성능이 떨어질 수 있습니다.
  • 추가 메모리 사용: 네이티브 코드의 캐싱으로 인해 추가 메모리 공간이 필요합니다.

요약

JIT 컴파일러는 Java 애플리케이션이 실행되는 동안 자주 사용되는 코드 영역을 네이티브 코드로 컴파일하여 성능을 최적화합니다.

이 과정은 JVM이 바이트코드를 해석하는 대신 네이티브 코드를 직접 실행함으로써 더 빠른 실행 속도를 제공합니다.

JIT 컴파일러는 Java의 플랫폼 독립성과 높은 성능을 동시에 가능하게 하는 중요한 요소입니다.

 

 

 

 

 


 

JDK > JRE > JVM

https://catch-me-java.tistory.com/11?category=438116

 

 

1. JVM (Java Virtual Machine)

역할

  • 실행 환경: JVM은 Java 바이트코드를 실행할 수 있는 가상 머신입니다. Java 애플리케이션의 실행을 담당하며, 플랫폼 독립적인 실행 환경을 제공합니다.
  • 바이트코드 해석: JVM은 .class 파일에 저장된 Java 바이트코드를 해석하고 실행합니다. 바이트코드는 JVM이 이해할 수 있는 중간 코드입니다.
  • 메모리 관리: JVM은 자동으로 메모리 관리를 수행하며, 가비지 컬렉션을 통해 불필요한 객체를 정리합니다.
  • 다양한 플랫폼 지원: JVM은 다양한 운영 체제에서 Java 애플리케이션을 실행할 수 있도록 설계되어 있으며, 특정 플랫폼에 맞는 JVM 구현체가 필요합니다.

구성 요소

  • 클래스 로더: 바이트코드를 메모리에 로드하고 클래스 정보를 관리합니다.
  • 런타임 데이터 영역: 메서드 스택, 힙, 메소드 영역 등을 포함하여 Java 애플리케이션이 실행되는 메모리 공간을 제공합니다.
  • Execution Engine: 바이트코드를 해석하고 JIT(Just-In-Time) 컴파일러를 통해 바이트코드를 네이티브 코드로 변환하여 실행합니다.

2. JRE (Java Runtime Environment)

역할

  • 런타임 환경: JRE는 JVM과 Java 애플리케이션 실행에 필요한 기본 클래스 라이브러리 및 기타 리소스를 포함하는 실행 환경입니다.
  • JVM 포함: JRE는 JVM을 포함하여 Java 프로그램이 실행될 수 있는 환경을 제공합니다.
  • 핵심 라이브러리: Java 표준 라이브러리(예: java.lang, java.util, java.io 등)를 포함하여 Java 애플리케이션이 실행되는 데 필요한 기본 클래스와 API를 제공합니다.

구성 요소

  • JVM: 바이트코드를 해석하고 실행하는 가상 머신.
  • Java 클래스 라이브러리: Java API의 핵심 클래스와 인터페이스를 포함합니다.
  • 기타 리소스: Java 애플리케이션 실행에 필요한 기타 리소스와 설정 파일.

3. JDK (Java Development Kit)

역할

  • 개발 도구 모음: JDK는 Java 애플리케이션을 개발하기 위한 도구와 라이브러리를 포함하는 개발 키트입니다.
  • JRE 포함: JDK는 JRE를 포함하고 있어, 개발된 Java 애플리케이션을 실행하고 테스트할 수 있습니다.
  • 컴파일러와 도구: Java 소스 코드(.java)를 바이트코드(.class)로 컴파일하기 위한 javac 컴파일러와, 디버깅, 문서화 등의 다양한 개발 도구를 포함합니다.

구성 요소

  • JRE: Java 애플리케이션을 실행하는 데 필요한 런타임 환경.
  • Java 컴파일러 (javac): Java 소스 코드를 바이트코드로 변환하는 도구.
  • 디버거 (jdb): Java 프로그램의 디버깅을 지원하는 도구.
  • 기타 개발 도구: Java 애플리케이션의 빌드, 패키징, 문서화 등을 지원하는 다양한 도구.

요약

  • JVM (Java Virtual Machine): Java 바이트코드를 실행하는 가상 머신. 플랫폼 독립적 실행 환경을 제공.
  • JRE (Java Runtime Environment): JVM과 Java 애플리케이션 실행에 필요한 라이브러리와 리소스를 포함하는 런타임 환경.
  • JDK (Java Development Kit): JRE를 포함하고, Java 애플리케이션 개발에 필요한 컴파일러, 디버거, 기타 개발 도구를 제공.

이러한 관계를 통해, JDK는 Java 애플리케이션의 개발과 실행을 위한 모든 기능을 포함하며, JRE는 애플리케이션 실행을 위한 환경을 제공하고, JVM은 실제 바이트코드를 실행하는 핵심 구성 요소입니다.

 

'CS Study' 카테고리의 다른 글

8월 4주차 GC  (0) 2024.08.19
8월 4주차 jar, war  (0) 2024.08.19
8월 3주차  (0) 2024.08.12
8월 2주차 - 개인 질문  (0) 2024.08.05
8월 2주차 - 공통 질문  (0) 2024.08.05