.java를 JVM으로 실행하는 과정 이해하기

노력을 즐기는 사람·2020년 11월 8일
1
post-thumbnail

목차

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

핵심: JIT = Runtime , javac = Compile / javac, javap 옵션들도 좀 보자

JVM이란 무엇인가?

Java Virtual Machine 의 약자로서 컴퓨터가 자바 바이트코드로 컴파일된 모든 프로그램을 실행할 수 있도록한다.
즉, JVM은 코드를 실행할 수 있는 런타임 환경을 제공하는 소프트웨어이다.

JVM의 두가지 특징

  • 자바 프로그램을 디바이스, OS 상관없이 모두 실행 가능하도록 한다.
    Write once, run anywhere !

  • 프로그램 메모리를 관리, 최적화 한다.

자바는 1995년에 세상에 등장했는데 모든 컴퓨터는 특정한 OS에서만 동작을 했고 프로그램 메모리 관리도 개발자에 의해서 수행되었다고 한다.
그래서 JVM은 혁신이였다고 한다.

내 의견 아님

.java 컴파일하기

요즘은 IntelliJ, Eclipse 를 많이 활용하기 때문에 .java 를 컴파일 하는 방법을 모르는 사람들이 많다. 심지어 전공자들도 잘 모르더라.

사실 직접 .java 을 컴파일 할 일이 있나 싶긴하다. 아직 학생이라 그런가 그런 상황을 마주한 적이 없다. 그래도 알아 놓으면 나쁠건 없으니 실습해보자.

만약 자바 입문서를 처음부터 따라해본 사람이라면 완벽하게 외우고 있지는 않아도 어렴풋이 기억하고 있을텐데 어쨌든 한번 실습해봅시다.

OpenJDK 11 버전을 설치하고 환경변수를 설정했다고 가정하고 실습을 진행한다. (Windows 10 기준)

그냥 메모장으로 아래와 같이 기본적인 구조의 자바 클래스를 생성하자

public class Compile {
  public static void main(String[] args) {
    System.out.println("Hello, JAVAC");
  }
}

그리고 해당 파일을 javac를 활용해서 컴파일한다.

그러면 *.class 가 생긴다.

.class 실행하기

그냥 뒤에 .class 를 떼고 java 커맨드로 실행시킬 수 있다.

바이트코드란 무엇인가?

바이트코드는 특정 하드웨어가 아닌 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진 표현법이다. 소프트웨어에 의해서 처리되기 때문에 기계어보다 더 추상적이라고 한다.
바이트 코드는 명령어의 집합이다. 프로그램이 특정 하드웨어에 의존하게 되는 것을 줄이고자 고안되었다.

프로그래밍 언어 -> 바이트코드 -> 기계어 이런식인듯?

자바 바이트코드

자바 바이트코드는 JVM이 실행하는 명령어 집합이다. 자바 바이트코드는 .class 이 담고 있다. 그래서 .java 는 사용자가 작성한 프로그래밍언어이고 .class 는 컴파일러가 프로그래밍 언어를 컴퓨터중심적으로 바꾼 바이트 코드인 듯 하다.

JVM 안에 있는 JRE 에서 Bytecode verifier 이라는 녀석이 바이트 코드를 처리하기 때문에 자바가 개발환경 독립적으로 동작할 수 있는 듯하다.

JIT 컴파일러란?

Just In Time 의 약자이다. 함께 언급되는 키워드로는 동적 컴파일, 런타임 컴파일이 있는 듯 하다. 그러니까 프로그램을 실행하는 동안에도 무언가 컴파일을 하는 듯 하다.

인터프리터 + 컴파일 방식의 혼합이라고 한다.

어떻게 동작하는가?

프로그램 실행 시점에 인터프리트 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱하여 같은 함수가 여러번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다고 한다.
이를 통해 성능을 향상 시킨다고 한다.

자바 프로그램 동작방식
.java 프로그래밍 -> 자바 컴파일러 -> .class 바이트코드 -> JIT 컴파일러 -> 기계어

JVM 구성요소

  • Class loader
    컴파일 타임이 아니라 런타임 때 클래스를 로딩할 수 있게 한다.
    클래스 로더도 계층 구조를 가질 수 있다. 즉, 부모 클래스 로더가 있을 수 있다는 뜻이다.
    그래서 클래스 로더는 Bootstrap <- Extension <- Application 의 구조를 가진다. (왼쪽으로 갈수록 최상위)

클래스 로더가 클래스를 로딩할 때 가장 먼저 하는 일은 이미 로딩이 되어 있는 클래스인지를 확인하는 것이다. 만약 로딩이 되어 있다면 캐싱이 되어 있을 것이고 이 경우에 캐싱된 값을 리턴해준다.

만약 로딩이 되어 있지 않다면 부모에게 클래스 로딩을 위임하고 부모가 클래스를 로딩할 수 없다면

  • JVM Memory
  • Execution Engine
  • Native Method Interface
  • Native Method Libraries

참고링크

JDK와 JRE의 차이

JDK란?

Java Development Kit 의 약자이다. 즉 자바 프로그램을 작성하고 컴파일 할 수 있다. JRE를 포함한다.

JRE란?

Java Runtime Environment 의 약자이다. JDK에서 프로그램 개발에 대한 부분을 제외한 프로그램이다.

profile
노력하는 자는 즐기는 자를 이길 수 없다

0개의 댓글