JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가

Jeongmin Yeo (Ethan)·2020년 11월 15일
3

STUDY HALLE

목록 보기
1/13
post-thumbnail

자바 소스 파일 (.java)를 JVM으로 실행하는 과정 이해하기

백기선님과 함께하는 자바 1주차 스터디 과정입니다.

학습할 내용은 다음과 같습니다.

  • JVM이란 무엇인가
  • 컴파일 하는 방법
  • 실행하는 방법
  • 바이트코드란 무엇인가
  • JIT 컴파일러란 무엇이며 어떻게 동작하는지
  • JVM 구성 요소
  • JDK와 JRE의 차이

Reference: Java in a Nutshell


JVM (Java Virtual Machine)이란 무엇인가?

  • 자바 가상머신으로 자바 바이트코드(.class)를 자바 실행코드로 변환해서 실행합니다.

  • 자바로 작성한 모든 프로그램은 자바 가상 머신에서 실행될 수 있습니다. 따라서 JVM은 반드시 필요합니다.

  • JVM은 운영체제 위에서 동작하는데 서로 다른 운영체제를 가지고 있더라도 JVM만 설치되어 있다면 같은 자바 프로그램은 아무런 문제없이 동작하는게 가능합니다. 그렇기 때문에 개발자는 단 하나의 프로그램만 배포하면 됩니다.

  • 하지만 자바 가상 머신은 운영체제에 종속적이기 때문에 각 운영체제에 맞는 자바 가상머신을 설치해야합니다

  • 그리고 일반 프로그램은 자바 가상 머신이라는 한 단계를 더 거쳐야하기 떄문에 실행속도가 느리다는 단점이 있습니다.

  • 바이트 코드를 JIT or 인터프리터로 실행을 해서 OS에 맞는 기계어로 변환되서 실행합니다.

  • JVM은 홀로 배포되지 않고 JRE (Java Runtime Environment) 형식으로 배포됩니다.


컴파일 하는 방법

  • javac라는 자바 컴파일러에 의해 자바 소스코드는 바이트코드(.class)파일로 컴파일 됩니다.
    • javac는 JDK에 포함된 자바 컴파일러입니다.
  • 컴파일 된 파일은 .class 확장자가 붙습니다.

실행하는 방법

  • 컴파일된 .class 파일을 “java”명령어를 사용하여 실행할 수 있습니다.

  • 실행 명령어는 다음과 같습니다. 실행할 때는 java명령어를 사용하고, 파일 확장자(.class)를 뺀 클래스 이름만 써주면 됩니다.


Java Bytecode란 무엇인가?

  • 자바 바이트코드는 자바 컴파일러에 의해 바이트코드로 변환됩니다.

  • 자바 바이트 코드(.class 파일)란 JVM이 이해할 수 있는 언어로 변환된 자바 소스 코드를 말합니다.

  • 자바 컴파일러에 의해 변환된 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불리고 있습니다.

// 아래와 같은 자바 코드가 있다고 생각해봅시다. 
for (int i = 2; i < 1000; i++) {
    for (int j = 2; j < i; j++) {
        if (i % j == 0)
            continue outer;
    }
    System.out.println (i);
}

// 자바 컴파일러는 은 이 자바 코드를 바이트 코드로 변환합니다. 
0:   iconst_2
1:   istore_1
2:   iload_1
3:   sipush  1000
6:   if_icmpge       44
9:   iconst_2
10:  istore_2
11:  iload_2
12:  iload_1
13:  if_icmpge       31
16:  iload_1
17:  iload_2
18:  irem
19:  ifne    25
22:  goto    38
25:  iinc    2, 1
28:  goto    11
31:  getstatic       #84; // Field java/lang/System.out:Ljava/io/PrintStream;
34:  iload_1
35:  invokevirtual   #85; // Method java/io/PrintStream.println:(I)V
38:  iinc    1, 1
41:  goto    2
44:  return

JIT 컴파일러는 무엇이고 어떻게 동작하는가?

  • 자바 컴파일러가 생성한 자바 바이트 코드를 런타임에 바로 기계어로 변환하는 역할을 합니다

  • 프로그램을 실행 시점에 기게어로 변환해주는 컴파일러를 말합니다

  • 이 방법은 Dynamic translation이라고 불리고 프로그램의 실행 속도를 향상시키기 위해 개발되었습니다.

  • 전통적인 방식에서 프로그램을 실행시키는 방법은 인터프리터 방식과 컴파일 방식이 있습니다.

    • 인터프리터 방식은 실행 중 프로그래밍 언어를 읽어가며 해당 기능에 대응하는 기계어 코드로 변환하는 과정 입니다.
    • 정적 컴파일은 프로그램 실행 전 프로그램 코드를 기계어로 번역 해놓은 걸 말합니다.
  • JIT 컴파일은 두 가지의 방식을 혼합해서 사용합니다. 실행 시점에 인터프리트 방식으로 기계어를 생성하고 그 코드를 캐싱합니다. 그래서 같은 함수가 여러번 실행되면 캐싱된 코드를 가져와서 매번 같은 기계어가 생성되는 걸 방지합니다.

  • 일반적인 인터프리터 언어는 바이트 코드나 소스코드 최적화 과정이 업기 때문에 성능이 낮습니다. 컴파일 하는 언어는 실행 전에 무조건 컴파일 해야하기 때문에 다양한 플랫폼에 맞게 컴파일 할려면 시간이 오래걸립니다. JVM에서 실행하는 JIT 컴파일러는 복잡한 최적화는 자바 컴파일러가 해줬기 때문에 고려하지 않아도 되고 바이트 코드 자체가 빠른 기계어로 변환을 목적으로 설계되었기 때문에 실행속도나 성능에서 우월합니다.


JVM의 구성 요소

예전에 JVM에 대해 공부했던 글이 있습니다. 다음 글을 참고해주세요.

https://velog.io/@youngerjesus/JVM-JDK-JRE%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C


JDK와 JRE의 차이

  • JRE (Java Runtime Environment)

    • Java Runtime Environment는 자바 애플리케이션을 생성하고 실행하는 데 목적을 둔 필요한 최소 구성 요소이며 JDK의 일부입니다.
  • JDK (Java Development Kit)

    • JDK는 Java 소프트웨어를 개발하는데 필요한 모든 것을 말합니다.
    • JDK에는 jre에는 없는 자바 소스 파일을 바이트코드로 변환해주는 javac, 소스 코드 주석으로부터 자동으로 문서를 생성해주는 툴인 javadoc, 자바 디버깅 툴인 jdb 등이 포함되어 있습니다.
  • 둘의 차이는 JDK는 Java 소프트웨어를 개발하는데 필요한 것들인 반면 JRE는 Java 애플리케이션을 프로그래밍하고 실행하는데 필요한 툴로 구성되어 있습니다.


자바 소스 파일 (.java)를 JVM으로 실행하는 과정

컴파일 타입의 환경

  1. Java 소스 코드를 작성합니다.
  2. 자바 컴파일러에 의해 자바 소스코드를 자바 바이트 코드로 변환합니다.

런타임 환경

  1. 클래스 로더(Class Loader)가 확장자가 .class 파일의 위치를 찾아 JVM위에 동적 로드합니다.
    • 여기에 있는 클래스 파일은 Native C로 구현된 핵심 자바 라이브러리, 자바 확장 클래스 파일, 개발자가 작성한 클래스 파일을 말합니다.
  2. JVM의 JIT 컴파일러가 자바 바이트 코드를 읽고 기계어로 해석하면서 프로그램을 실행합니다.
profile
좋은 습관을 가지고 싶은 평범한 개발자입니다.

0개의 댓글