Language/Java

JVM(Java Virtual Machine)과 Java 컴파일 과정

settong 2024. 11. 29. 10:53
반응형

JVM(Java Virtual Machine)이란?

JVM의 정의와 특징

JVM은 Java 바이트코드를 실행하는 가상 컴퓨팅 엔진이다.

주요 특징은 다음과 같다.

  • ⭐️ 플랫폼 독립성 : 다양한 OS에서 자바 프로그램을 실행할 수 있음.
  • 메모리 관리 : 가비지 컬렉션을 통한 자동 메모리 관리.
  • 바이트코드 실행 : 컴파일된 바이트코드를 기계어로 변환하여 실행.

 

JVM의 구조

아래의 이미지는 JVM의 구조이다. 크게 Class Loader, Runtime Data Area, Execution Engine으로 나눌 수 있다.

JVM Architecture

 

  • 클래스 로더(Class Loader): 자바 클래스를 로드하고 링크하여 런타임 데이터 영역에 배치.
    • Bootstrap Class Loader: JVM이 시작될 때 가장 먼저 로드되는 클래스 로더로, JDK의 핵심 클래스 라이브러리(JRE/lib/rt.jar)를 로드.
    • Extension Class Loader: 확장 클래스 라이브러리를 로드(JRE/lib/ext 디렉터리).
    • Application Class Loader: 응용 프로그램의 클래스 경로에 있는 클래스를 로드(classpath)
  • 런타임 데이터 영역(Runtime Data Area)
    • 메서드 영역(Method Area): 클래스 구조와 메서드 코드를 저장.
    • 힙 영역(Heap Area): 객체와 인스턴스 변수를 저장.
    • 스택 영역(Stack Area): 지역변수와 부분 결과를 저장.
    • PC 레지스터(PC Register): 현재 실행중인 명령의 주소를 저장
    • 네이티브 메서드 스택(Native Method Stack): 네이티브 코드 실행에 사용.
  • 실행 엔진 (Execution): 인터프리터와 JIT 컴파일러를 사용하여 바이트코드를 실행.
    • 인터프리터(Interpreter): 바이트 코드를 한 줄씩 읽어 해석하고 실행. 초기 실행 시 빠르지만, 반복적인 작업에서는 비효율적일 수 있음.
    • JIT 컴파일러(JIT Compielr): 실행 중인 바이트 코드를 기계어로 변환하여 성능을 향상시킴. JIT 컴파일러는 자주 실행되는 코드를 캐시에 저장하여 이후 실행 속도를 높임.
      • C1 컴파일러: 빠른 컴파일을 목표로 하며, 간단한 최적화를 수행.
      • C2 컴파일러: 고급 최적화를 수행하여 실행 성능을 크게 향상시킴.
    • 가비지 컬렉터(Garbage Collector): 더 이상 사용되지 않는 객체의 메모리를 자동으로 해제.
  Interpreter JIT(Just In Time) 컴파일러
특징 바이트 코드를 한 줄씩 읽고 실행.
즉시 실행 가능 -> 프로그램 시작 시 딜레이가 적음.
디버깅이 용이하고 초기 오버헤드가 낮음.
자주 실행되는 바이트 코드 전체를 네이티브 머신 코드로 컴파일하여 성능 향상.
실행 중 코드 실행 패턴을 분석하고 런타임 정보를 활용하여 최적화를 수행.
프로그램이 실행되는 동안 필요한 부분만 컴파일 하므로 전체 프로그램을 처음부터 컴파일할 필요 없음
단점 ❗️ 반복적 연산이 많은 경우 반복적으로 바이트 코드를 해석해야 하므로 런타임 오버헤드가 발생할 수 있으며, 한 줄씩 해석하기 때문에 성능이 떨어질 수 있음 ❗️ 초기 오버헤드가 발생할 수 있고, 변환 코드를 저장하기 위한 추가 메모리 필요.

 

 

 

 

 


Java 컴파일 과정

 

 

  1. 소스 코드 작성
    • 개발자가 .java 확장자를 가진 자바 소스 코드 파일을 작성.
  2. 컴파일
    • 자바 컴파일러(javac)가 소스 코드(.java)를 읽어 바이트코드(.class)로 변환 시도.
  3. 바이트코드 생성
    • 컴파일이 성공하면 .class 확장자를 가진 바이트 코드 파일이 생성.
    • 이 바이트 코드는 컴퓨터에서 직접 실행 불가. JVM만 이해하는 중간 코드임.
    • 컴파일된 바이트코드(.class)는 JVM의 클래스 로더에 전달. 
  4. 클래스 로더 동작
    • 클래스 로더는 .class 파일을 JVM 메모리에 로드함.
    • 그 외에도 검증, 준비, 분석, 초기화 과정을 거침.
      • 검증: 자바 언어 명세 및 JVM 명세에 맞게 구성되었는지 검사.
      • 준비: 클래스가 필요로 하는 메모리를 할당.
      • 분석: java/lang/String 형태의 심볼릭 레퍼런스를 0x5f3759df(메모리 주소) 형태의 다이렉트 레퍼런스로 변경.
      • 초기화: 클래스 변수들을 적절한 값으로 초기화.
    • 동적 로딩을 통해 필요한 클래스들을 로딩 및 링크하여 Runtime Data Area에 배치.
  5. 실행
    • JVM의 실행 엔진(Execution Engine)이 메모리에 로드된 바이트코드를 실행.
    • 초기에는 인터프리터 방식으로 바이트 코드를 실행.
    • 이후, 프로그램이 '워밍업'되면서 자주 실행되는 코드(핫스팟)를 JIT컴파일러로 컴파일함.

 

 

 

 

728x90
반응형