JVM 이해하기

무심코·2023년 1월 4일
1

JVM

직역하면 '자바를 실행하기 위한 가상 기계(컴퓨터)'라고 할 수 있다.
Java 는 OS에 종속적이지 않다는 특징을 가지고 있다. OS에 종속받지 않고 실행되기 위해선 OS 위에서 Java 를 실행시킬 무언가가 필요하다. 그게 바로 JVM이다.
즉, OS에 종속받지 않고 CPU 가 Java를 인식, 실행할 수 있게 하는 가상 컴퓨터이다.

Java 소스코드, 즉 원시코드(*.java)는 CPU가 인식을 하지 못하므로 기계어로 컴파일을 해줘야한다.
하지만 Java는 이 JVM 이라는 가상머신을 거쳐서 OS에 도달하기 때문에 OS가 인식할 수 있는 기계어로 바로(한번에) 컴파일 되는게 아니라 JVM이 인식할 수 있는 Java bytecode(*.class)로 변환된다.

Java compiler 가 .java 파일을 .class 라는 Java bytecode로 변환한다.
여기서 Java compiler 는 JDK를 설치하면 bin 에 존재하는 javac.exe를 말한다. (즉, JDK에 Java compiler가 포함되어 있다는 소리임) javac 명령어를 통해 .java를 .class로 컴파일 할 수 있다.

변환된 bytecode는 기계어가 아니기 때문에 OS에서 바로 실행되지 않는다.
이 때, JVM이 OS가 bytecode를 이해할 수 있도록 해석해준다. 따라서 Byte Code는 JVM 위에서 OS 상관없이 실행될 수 있는 것이다.
즉 JAVA는 OS에 종속적이지 않고, Java 파일 하나만 만들면 어느 디바이스든 JVM 위에서 실행할 수 있다.

How to compile?

Java Compiler는 JDK를 설치하면 javac.exe라는 실행 파일 형태로 설치된다. 정확히는 JDK 의 bin 폴더에 javac.exe 로 존재한다.
Java Complier 의 javac 라는 명령어를 사용하면 .class 파일을 생성할 수 있다.

Mac Terminal에서 컴파일하는 방법은 다음과 같다

  1. 컴파일을 하기 위한 Java 파일이 있는 디렉토리로 이동
  2. javac *.java 명령어로 컴파일
  3. *.class 파일이 생성된 것을 확인할 수 있음
  4. 여기서 실행까지 시키고 싶다면 java *파일명 으로 실행

Java Bytecode

자바 바이트 코드(Java bytecode)는 JVM이 이해할 수 있는 언어로 변환된 자바 소스코드를 의미한다.
자바 컴파일러에 의해 변환된 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불리고 있다.
바이트 코드는 다시 실시간 번역기 또는 JIT 컴파일러에 의해 바이너리 코드로 변환된다.

🦭 Java Source code 변환 과정
소스코드 → [ 🏭 자바 컴파일러 ] → 바이트 코드(JVM이 이해 가능) → [ 🏭 실시간 번역기 or JIT 컴파일러 ] → 바이너리 코드(OS가 이해 가능)

JIT 컴파일러

JIT 컴파일러(just-in-time compliation)는 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일러이다.
JIT 컴파일(just-in-time compliation)은 동적 번역(dynamic translation) 이라고도 한다.
인터프리터 방식의 단점을 보완하기 위해 도입되었다.

  • 인터프리터 방식이란?
    고급언어로 작성된 프로그램 전체를 한 번에 기계어로 번역한 후 링킹 작업을 거쳐 컴퓨터에서 실행 가능한 프로그램을 만드는 컴파일러(Compiler) 방식과는 다르게 인터프리터(Interpreter) 방식은 고급언어로 작성된 프로그램을 한 줄씩 기계어로 번역 후 즉시 실행시키는 방식이다.

인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변경하고, 이후에는 해당 더 이상 인터프리팅 하지 않고 기계어로 직접 실행하는 방식이다.

기계어(컴파일된 코드)는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 빠르게 수행하게 된다. 물론 JIT 컴파일러가 컴파일하는 과정(먼저 인터프리팅하다가 일정 시점에서 진행하는 컴파일 과정을 말함)은 바이트 코드를 그냥 인터프리팅하는 것보다 훨씬 오래걸리므로 한 번만 실행되는 코드라면 컴파일 하지 않고 인터프리팅하는 것이 유리하다.

따라서 JIT 컴파일러를 사용하는 JVM들은 내부적으로 해당 메서드가 얼마나 자주 수행되는지 체크하고 일정 정도를 넣을때에만 컴파일을 수행한다.

profile
지나치지 않기 위하여

0개의 댓글