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

라모스·2021년 8월 23일
1

Java☕

목록 보기
1/14
post-thumbnail

// 블로그 이주 중으로 이전 블로그에 포스팅한 글들을 재구성하여 옮기고 있습니다.
해당 게시글

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

학습할 것

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

1. JVM이란 무엇인가?

Java Virtual Machine(JVM)이란 컴파일된 Java byte code를 기존 프로그래밍 언어가 가진 플랫폼 종속성을 극복하여 각각의 OS, H/W에 상관 없이 자바 프로그램이 동일하게 실행되도록 해석하여 실행시키는 역할을 한다.


// 기존 프로그래밍 언어


// Java의 JVM에 의한 WORA

즉 JVM이 제대로 설치 되어 있다면, 한번 작성된 코드는 플랫폼에 맞춰 리팩토링 할 필요 없이 모든 플랫폼에서 바로 실행 가능하다는 특징이 있다.

2. 컴파일과 실행하는 방법

C/C++ 프로그램의 경우, 여러 소스파일로 나누어 개발하고 링크를 통해 실행에 필요한 모든 코드를 하나의 실행파일(.exe)에 저장하고 이 실행 파일은 모두 메모리에 올려져야 실행된다. 메인 메모리의 크기가 작은 경우 불리함이 따른다. 컴파일은 코드를 읽고 해석하여 전체 소스코드를 기계어로 바꾸어 파일로 생성하기 때문에 빌드 과정은 오래걸리지만 막상 실행하면 기계어를 읽기만 하면 되기 때문에 빠르게 실행된다.

반면 Java에서 컴파일은 기존의 컴파일 과정과 조금 다르게 진행된다. Java의 컴파일러인 javac.exe는 JVM이 이해할 수 있게 중간 단계인 바이트 코드(.class)로 변환시켜 주고 프로그램을 실행하게 되면 JVM이 이 바이트 코드를 기계어로 변환시켜 실행하게 된다. 바이트 코드를 하나의 실행 파일로 만드는 링크 과정이 없다. 실행의 경우 main()메소드를 가진 클래스에서부터 시작되고, JVM은 필요할 때 클래스 파일을 로딩하여 실행 하기 때문에 적은 메모리로 실행이 가능하다는 특징이 있다.

// hello.java 파일을 생성하여 다음과 같은 코드를 예시로 작성한다.
public class Hello {
    public static void main(String args[]) {
        System.out.println("Hello, Java!");
    }
}
// javac.exe를 이용해서 터미널 환경에서 다음과 같은 명령어를 입력하여 컴파일 한다.
> javac Hello.java

// 정상적으로 되지 않았다면
> %자바설치위치%\bin\javac Hello.java
-----------------------------------------------------------------

// 다음과 같이 실행(.class 확장자를 붙이지 않는다)
> java Hello


터미널 창에서 이와 같이 실행하면 class 확장자의 바이트 코드를 JVM이 읽어서 실행하게 된다.

3. 바이트코드란 무엇인가?

JVM에서 실행 가능한 바이너리 코드로 바이트 코드는 컴퓨터 CPU에 의해 직접 실행되지 않는다. JVM이 작동 중인 플랫폼에서 실행하고, 인터프리터 방식으로 바이트 코드를 해석하게 된다. 자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1byte 라서 자바 바이트 코드라고 불리고 있으며, 확장자는 .class 이다.

4. JIT 컴파일러란 무엇이며 어떻게 동작하는가?

Just-In-Time compilation(JIT)란 프로그램을 실제 실행하는 시점에서 기계어로 번역하는 컴파일 기법이다. 인터프리터 방식과 컴파일 방식을 혼합한 방식으로 볼 수있고, 실행시점에 인터프리터 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱하여 같은 함수가 여러 번 호출될 때 매번 생성하는 것을 방지한다.

일반적인 인터프리터 언어에서는 소스코드를 최적화 과정없이 번역하기 때문에 성능이 떨어지고 컴파일 언어에서는 실행 전에 무조건 컴파일을 시행하여야 하기 때문에 다양한 플랫폼에 맞춰 컴파일을 하려면 시간이 오래걸리게 된다. JIT 컴파일러에서는 최적화를 미리 해줌으로써 인터프리터 언어의 단점을 보완하고 플랫폼에 맞게 수정해야 하는 컴파일 언어의 단점을 가상머신을 통해 실행함으로써 보완할 수 있다. 다만, 컴파일하는 과정은 바이트코드를 인터프리팅 하는 것보다 훨씬 오래걸린다는 단점이있다.


// 출처: https://m.blog.naver.com/ki630808/221844888233

5. JVM 구성요소

JVM은 Class loader, Runtime Data Areas, Execution Engine, Garbage Collector로 나누어 진다.

  • Class Loader

    실행하는 시점에 자바로 코드를 컴파일하여 나온 .class 형식의 자바 바이트 코드를 런타임에 동적으로 메모리에 로드하게 해준다.

  • Execution Engine

    Class Loader에 의해 메모리로 로딩된 이후 실질적으로 JVM을 실행하는 모듈이다.

  • Runtime Data Area

    프로그램을 수행하기 위해 OS로부터 별도로 할당받은 메모리 공간을 의미함. 운영체제 과목에서 공부하는 메모리 구조와 같이 PC Register, Stack, Heap 영역이 존재한다.

  • Garbage Collector

    프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된 영역을 해제하는 기능이다. 개발자는 이 때문에 비즈니스 로직에만 집중할 수 있게 되는 편리한 기능이다.

// C언어에선 malloc 하면 free는 세트로 해줘야 했음...

가비지 콜렉터에 대한 자세한 내용은 이 내용을 읽어보자.
가비지 콜렉터 - wikipedia

6. JDK와 JRE의 차이?

JDK(Java Development Kit)는 자바 응용 개발 환경으로 개발에 필요한 도구들이 포함되어 있다. 자바의 모든 기능을 포함한 SDK이다.

// 컴파일러, 컴파일된 자바 API 클래스들이 들어 있는 모듈 파일들, 샘플 등 포함

JRE(Java Runtime Environment)는 자바 실행 환경으로, JVM, java 클래스 라이브러리 등 프로그램을 실행하는데 필요한 모든 것을 포함한 패키지이다.

References

  • 명품 Java Programming
  • Java의 정석 3판
profile
Step by step goes a long way.

0개의 댓글