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

kwang·2022년 6월 23일
0

Java-Live-Study

목록 보기
2/15

목표


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

학습할 것


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

실행과정


JVM이란 무엇인가


Java Virtual Machine의 줄임말로 자바를 실행하기 위한 가상 기계라고 할 수 있다.

Java는 OS에 종속되지 않는다. 따라서 실행되기 위해선 OS 위에서 Java를

실행시킬 무언가가 필요한데 이게 JVM이다.

그렇다면 JVM이 .java파일을 바로 읽어서 실행시키나?

그것은 아니다.

.java 파일은 사람이 코드를 쓰기 위해서 쓰는 파일이고 이를 실제로 기계가

인식할 수 있는 기계어로 변환하기 위해서는 .class파일(Java bytecode)로

변환되어야 한다.

이렇게 변환된 .class파일은 JVM이 OS에 상관없이 실행되게끔 해석,실행 해준다.

컴파일 하는 방법

  • Java compiler
    .java파일을 .class파일로 변환해주는 번연기라고 생각하면 된다.
    Java 개발시 설치하게되는 JDK 내부에 bin폴더에 javac.exe가 존재하는데 이게 바로 Java compiler이다.

1. IDE를 이용하는 방법

이 방법은 이클립스나 인텔리제이 같은 프로그램을 사용하여 자바파일을

실행하거나 auto compile 기능을 켜두면 .class파일이 생성되는 방법이다.

2. javac를 이용하는 방법

사실 이 방법이 학습목적의 더 맞는 방법일거다.

먼저 테스트를 위해 Test.java파일을 하나 만들었다.

javac 자바파일명.java를 입력해주면 위에서 설명한 자바컴파일러가

.class파일을 생성해준다.(여기서 javac가 제대로 동작하려면 환경변수가 등록 되어야한다.)

실행하는 방법

java.exe? javac.exe?

위에서 javac가 .java파일을 .class파일로 변경해주는 컴파일러라고 설명을 했다.

그럼 java.exe는 뭘까? 바로 JVM을 실행시키기 위한 명령 프로그램이다.

java class파일명 명령어로 JVM을 실행시킬 수 있다.

여기서 중요한건 Test.class파일이라면 java Test처럼 .class를 빼고 입력 해야된다.

Hello World가 정상적으로 보이는것을 확인 할 수 있다.

바이트코드란 무엇인가

컴파일러가 변환한 .class파일이 바이트 코드로 이루어진 파일이다.

이러한 바이트 코드는 JVM이 이해할 수 있는 언어이다.

하지만 자바 프로그램이 실행될 때 .class파일이 바로 실행되는 것이 아니다.

아래에서 어떠한 과정을 더 거치는지 알아보겠다.

JIT 컴파일러란 무엇이며 어떻게 동작하는지

  • 바이너리 코드
    CPU가 이해하는 언어
    기계어

JIT컴파일(just-in-time compilation)로 자바에서는 프로그램이 실행되어 컴파일된

파일을 인터프린터 방식으로 실행되는데 코드가 실행되는 시점에 사용되는

코드(바이트 코드)를 바이너리 코드(기계어)로 컴파일해주어 인터프린터가 해석을

하지 않고 바로 실행할 수 있게 도와준다.

결국 인터프린터 방식과 컴파일 방식이 동시에 사용되어 상호작용으로

성능을 향상 시킵니다.

JVM 구성 요소

위에서 봤던 자바 실행순서이다.

그림을 보면 JVM이 중요한 역할을 한다는 걸 알 수 있다.

  • 실행순서
    1. Class Loader를 통해 .class파일들을 JVM에 올린다.
    2. JVM에 있는 .class 파일들을 Execution Engine의 Interpreter와
      JIT Compiler를 통해 해석한다.
    3. 해석된 바이트 코드는 Runtime Data Area에 배치되어 실행된다.

Class Loader

JVM내로 클래스 파일을 로드하고 링킹을 통해 배치하는 작업을 한다.

런타임시 동적으로 클래스를 로드하고 jar파일내 저장된 클래스들을 JVM에 올린다.

Execution Engine

클래스를 실행하는 역할로 Runtime Data Area에 올라온 클래스들을 실행한다.

  • Interpreter
    자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
  • JIT
    일정시점에 바이트 코드를 컴파일하여 기계어로 변환하여 빠르게 실행한다.
  • Gabage Collecter
    인스턴스, 배열이 메모리를 차지하는데 사용 후 필요없어진 데이터를 메모리에서 삭제한다.

Runtime Data Area

JVM이 프로그램을 실행할 때 OS로부터 할당받는 메모리 영역이다.

위에 사진을 보면 상단 3개 영역은 Thread별로 생성되고 하단 2개 영역은

모든 Thread가 공유한다. 아래는 영역별로 알아보겠다.

  • PC Register
    Thread가 어떤 명령을 실행해야되는지에 대한 부분으로 현재 수행중인
    JVM 명령의 주소를 갖는다.
  • JVM stack
    Thread의 Method가 호출될 때 수행정보(메소드 호출 주소, 매개 변수, 지역 변수등)가 Frame이라는 단위로 JVM stack에 저장된다.그리고 Method 종료될 때 stack에서 제거된다.
  • Native Method stack
    Java외의 언어로 작성된 네이티브 코드들을 위한 stack이다.
  • Heap
    인스턴스와 배열이 동적으로 생성되는 공간으로 Garbage Collection이 사용이 완료된 인스턴스, 배열을 제거해준다.
  • Method Area
    Class Loader가 올려놓은 클래스 정보를 저장하기 위한 메모리 공간이다. Heap영역에 속하는 부분이였지만 Java 8 이후로는 Metaspace라는 OS가 관리하는 영역으로 옮겨졌다.
  • Runtime Constant Pool
    static영역에 존재하는 별도의 관리영역으로 상수 자료형을 관리하여 중복을 막아준다.

JDK와 JRE의 차이

JDK (Java Development Kit)

Java를 사용하기 위해 필요한 모든 기능을 갖춘 키트이다.

Java 프로그램을 생성, 실행, 컴파일 할 수 있다.

JRE를 포함하고 있다.

JRE (Java Runtime Environment)

JVM + Java Class Library등으로 이루어져 있다.

컴파인된 Java프로그램을 실행시킬 수 있다.

0개의 댓글