JVM의 구조와 Java의 실행 방식

HyunJe Park·2024년 12월 16일
1

Java

목록 보기
1/2

JVM이란?

JVM(Java Virtual Machine)은 자바 가상 머신의 약자로 바이트 코드(.class 파일)을 실행하는 가상 기계다.

JVM이 존재하기에 운영체제나 하드웨어에 종속되지 않고, 어떤 환경에서든 자바 프로그램을 실행할 수 있다.

Java의 실행 개괄

JVM의 구조를 자세히 알아보기 이전에, 먼저 Java 코드를 실행하는 큰 틀을 설명하면 다음과 같다.

  1. 소스 코드를 자바 컴파일러(javac)가 컴파일하여 바이트 코드를 만든다.
  2. 바이트 코드를 JVM이 읽어들여서 실행하고 관리한다.

참고로, 아래는 Java에서 언급되는 코드관련 용어를 정리해보았다.

소스 코드: .java 확장자로 이루어진 파일이다. 자바 언어로 쓰여있다.
바이트 코드: .class 파일을 의미한다. 기계어는 아니고, 컴파일 후 생성되는 중간코드다. JVM이 읽어들일 수 있는 형식의 코드이다.
네이티브 코드: C, C++, 어셈블리어로 구성된 코드. JAVA에서 부모가 되는 언어를 의미한다.
기계어: 0,1의 이진 코드로 되어 있어서, CPU가 직접 해석하고 실행할 수 있는 언어를 의미한다.

JVM 구조

JVM의 구조는 Class Loader, Execution engine, Runtime Data Area, JNI, Native Method Library로 이루어져 있다.

클래스 로더(Class Loader)

JVM내로 클래스를 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈이다.

어플리케이션에서 필요한 경우에, 바이트 코드(.class)들을 JVM의 Runtime Data Area에 적재한다.

실행 엔진(Execution Engine)

Runtime Data Area에 있는 바이트 코드를 해석하고 실행한다.

실행 엔진의 구성 요소는 다음과 같다.

  1. 인터프리터
  2. JIT 컴파일러
  3. GC(Garbage Collector)

바이트 코드를 JVM 내부의 기계가 실행할 수 있는 기계어로 바꾸어 실행하는데, 인터프리터와 JIT 컴파일러를 혼합해 사용한다.

  • 인터프리터: 바이트 코드를 한줄 씩 실행한다.
    • JVM이 바이트 코드를 해석하는 기본적인 방식.
    • 간단하지만 실행 속도가 느릴 수 있다.
  • JIT 컴파일러(Just-in-Time): 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러가 반복되는 코드를 네이티브 코드로 바꾼다. 그 다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용한다.
    • 인터프리팅 방식보다 빠르다.(인터프리터의 단점 보완)
    • 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일한다.

메모리 관리를 위해 GC가 사용된다.

  • GC(Garbage Collector): 가비지 컬렉터로, 힙 영역에서 사용되지 않는 객체들을 제거하는 작업이다.

런타임 데이터 영역 (Runtime Data Area)

프로그램 실행 중에 사용되는 다양한 영역이다.

런타임 데이터 영역은 다음과 같다.

  1. 메서드 영역
  2. 힙 영역
  3. 스택 영역
  4. PC Register
  5. 네이티브 메서드 스택(Native Method Stack)

  1. 메서드 영역
    • 바이트 코드(.class)를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장한다.
    • 클래스 멤버 변수, 메서드 정보, Type 정보, Constant Pool, static, final 변수 등이 생성.
    • JVM 시작 시 생성되어 프로그램이 종료될 때까지 저장된다.
  2. 힙 영역
    • 객체, 배열 저장. GC의 대상 영역.
  3. 스택 영역
    • 메소드 호출 시 생성되는 지역 변수 등 생성. 객체는 힙 영역에 할당되지만, 레퍼런스는 스택 영역에 할당.
  4. PC Register
    • Thread가 시작될 때 생성. 현재 수행 중인 JVM 명령의 주소를 갖고 있다.
  5. 네이티브 메서드 스택(Native Method Stack)
    • 네이티브 코드를 위한 공간.

여기서 메서드 영역, 힙 영역은 모든 쓰레드가 공유한다.
스택 영역, PC Register, Native Method Stack 영역은 각 쓰레드마다 생성되고, 공유되지 않는다.

JNI(네이티브 메서드 인터페이스, Native Medthod Interface)

자바 애플리케이션에서 C, C++, 어셈블리어로 작성된 함수를 사용할 수 있는 방법을 제공한다.

네이티브 메서드 라이브러리 (Native Method Library)

C, C++로 작성된 라이브러리다.

Java의 실행방식

  • 자바 프로그램을 실행하면 JVM은 OS로부터 메모리를 할당받는다.
  • 자바 소스코드(.java)를 자바 컴파일러(javac)가 자바 바이트 코드(.class)로 컴파일한다.
  • Class Loader는 동적 로딩을 통해 필요한 클래스들을 읽어들이고, Runtime Data Area에 올린다.
  • Runtime Data Area에 로딩 된 바이트 코드를 Execution Engine이 실행한다.
  • Execution Engine에 의해 Garbage Collector의 작동이 이루어진다.

참고문헌

profile
사람은 기록을 만들고, 기록은 사람을 만든다

0개의 댓글