JVM 이해하기

무심코·2023년 1월 4일
1
post-custom-banner

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
지나치지 않기 위하여
post-custom-banner

0개의 댓글