개발자는 기록이 답이다

JVM이해하기 - 자바, JVM, JDK, JRE의 차이 본문

언어/Java

JVM이해하기 - 자바, JVM, JDK, JRE의 차이

slow-walker 2023. 11. 20. 09:16

 

 

 

 

 

JVM (Java Virtual Machine)

  • 자바 가상 머신으로 자바 바이트 코드(.class 파일)를 OS에 특화된 코드로 변환(인터프리터와 JIT 컴파일러)하여 실행한다.
  • 바이트 코드를 실행하는 표준(JVM 자체는 표준)이자 구현체(특정 밴더가 구현한 JVM)다.
  • JVM 스팩: https://docs.oracle.com/javase/specs/jvms/se11/html/
  • JVM 밴더: 오라클, 아마존, Azul, ...
  • 특정 플랫폼에 종속적.

$ vi ./HelloJava.java
public class HelloJava {
  public static void main(String args[]){
  System.out.println("Hello, Java");
  }
 }
// javac는 Java소스코드 파일을 컴파일하여 바이트 코드로 변환
$ javac HelloJava.java // JDK에 포함된 도구

// javap은 클래스파일의 바이트 코드를 해석하여 보여줌 (클래스 구조, 메서드, 필드 정보 얻을 수 있음)
// Java클래스의 실제 실행 코드를 나타냄
$ javap -c HelloJava // JDK에 포함된 도구

 

Java 언어는 소스 코드를 컴파일하면 클래스 파일이 생성되고, 이 파일 안에는 JVM이 이해할 수 있는 바이트 코드가 들어 있습니다. JVM은 이 바이트 코드를 실행하기 위해 두 가지 주요 방식을 사용합니다 -> 인터프리터와 JIT 컴파일러(Just-In-Time Compiler)

 

바이트 코드는 JVM에 의해 인터프리터나 JIT 컴파일러를 통해 실행됩니다. 인터프리터는 바이트 코드를 한 줄씩 해석하여 실행하는 방식으로 동작합니다. 반면, JIT 컴파일러는 실행 시점에 바이트 코드를 네이티브 머신 코드로 변환하여 실행합니다. 이는 프로그램의 실행 속도를 높이는 장점을 가지고 있습니다.

 

JVM은 OS에 특화된 머신 코드로 변환되어 실행되어야 합니다. 이 과정에서 JIT 컴파일러가 사용되며, Java 프로그램은 Native OS(예: 맥, 윈도우)에서 실행될 수 있도록 머신코드로 변경됩니다. 이는 JVM의 특성상 OS에 의존적이라는 것을 의미합니다.

 

JVM은 자바 가상 머신의 스펙을 정의하는 것으로, 여러 벤더들이 자신만의 구현체를 제공합니다. 이러한 다양성은 자바의 유연성을 보여주는 부분 중 하나입니다. 각 벤더는 JVM 스펙에 맞춰 자체적으로 구현하며, 이를 통해 Java 프로그램은 여러 플랫폼에서 실행 가능합니다.


JVM은 홀로 제공되지 않습니다. 최소한의 배포 단위는 JRE(Java Runtime Environment)입니다. 왜냐하면 네이티브코드로 바꿔서 실행해야 하는데 그 네이티브 코드가 OS에 맞춰서 실행되어야 하기 때문입니다. JRE는 JVM뿐만 아니라 Java 프로그램이 실행되기 위해 필요한 라이브러리와 기타 도구들을 포함하고 있습니다.

 

결국, JVM은 자바 언어의 핵심이자, 바이트 코드를 실행하는 엔진입니다. 그러나 그 동작은 JVM의 구현체에 따라 달라집니다. 이러한 특성으로 인해 Java 언어는 플랫폼에 의존적이지만, 다양한 환경에서 실행 가능하다는 장점을 가지게 됩니다. 자바의 유연성은 여러 플랫폼에서의 네이티브 코드 실행을 가능케 하며, 이는 Java가 다양한 환경에서 널리 사용되는 이유 중 하나입니다.

Compiled from "HelloJava.java"
public class HelloJava {
  public HelloJava();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #13                 // String Hello, Java
       5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

 

 

 

JRE (Java Runtime Environment): JVM + 라이브러리

  • 자바 애플리케이션을 실행할 수 있도록 구성된 배포판.
  • JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있다.
  • 개발 관련 도구는 포함하지 않는다. (그건 JDK에서 제공)

 

JDK (Java Development Kit): JRE + 개발 툴

    • JRE + 개발에 필요할 툴
    • 소스 코드를 작성할 때 사용하는 자바 언어는 플랫폼에 독립적.
    • 오라클은 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않는다.
    • Write Once Run Anywhere

자바

    • 프로그래밍 언어
    • JDK에 들어있는 자바 컴파일러(javac)를 사용하여 바이트코드(.class 파일)로 컴파일 할 수 있다.
    • 자바 유료화? 오라클에서 만든 Oracle JDK 11 버전부터 상용으로 사용할 때 유료.

JVM 언어

    • JVM 기반으로 동작하는 프로그래밍 언어
    • 클로저, 그루비, JRuby, Jython, Kotlin, Scala, ...
    • 사실상 Java와 의존성이 타이트하지 않다 -> 다른 프로그래밍 언어로 코딩 하더라도 만약에 그 언어를 컴파일 했을때 클래스 파일이 만들어지거나 Java파일을 만들어주기만 하면 JVM을 활용할 수 있다.

참고

 


 

컴파일 방법 & 과정

바이트 코드란

JVM과 JIT 컴파일러란?

JVM의 구조

JDK & JRE, 자바 실행