JVM - Java Virtual Machine

BK·2024년 7월 12일
0

Java

목록 보기
4/9

JVM 이란?

JVM stands for Java Virtual Machine

이름을 보면 Java에서 사용되는(?) Virtual Machine으로 느껴진다. 그럼 Virtual Machine은 뭔가

간단히 말해, 가상 머신, VM은 물리적 컴퓨터에서 실행하는 모든 소프트웨어를 실행하는 데 사용할 수 있는 "소프트웨어 컴퓨터"로 생각할 수 있습니다.

그럼 JVM은 Java를 실행하기 위한 Virtual Machine이라는 것인데, 왜 이런 VM이 필요한지는 Java의 특징에 대해 먼저 알아봐야 한다.

Java - WORA

Java는 OS 독립적인 언어이다. WORA(Write Once Run Anywhere)라는 말이 있을 정도로, Java의 중요한 특징이자 Java라는 언어가 많이 사용된 이유이다.

어떠한 프로그래밍 언어로 작성된 프로그램이 실행 되는 것은 컴퓨터의 자원을 사용하는 것인데, CPU나 메모리 등 컴퓨터의 자원을 관리하는 것은 OS가 수행하는 작업이다. 즉, 어떠한 프로그램이 동작하기 위해서는 OS와 상호작용이 필요하고, 프로그래밍은 이러한 OS에 자연스럽게 종속된다.

하지만, 위 그림과 같이 Java는 프로그램이 OS와 직접 상호작용 하는 것이 아니라, 그 사이에 JVM을 통해 프로그램과 JVM, 그리고 JVM과 OS가 상호작용을 하게 되어 OS 독립적인 프로그래밍 언어를 구현했다.

Java 실행 과정

Java는 실행 과정에서 CompileInterpret 과정을 모두 거치는 Hybrid 언어이다.

Java는 우선 OS가 실행 가능한 언어가 아닌, 우선 JVM이 해석 가능한 java byte code로 변환하는 과정을 거치는데, 이는 Java compiler에 의해 수행되며, 개발자가 작성한 .java 파일을 .class 파일로 변환한다. 이 Java compiler는 JDK와 함께 설치되며, javac 명령어를 통해 컴파일 할 수 있다.

jdk/bin/javac.exe

이렇게 생성된 .class 파일은 java 명령어를 통해 실행할 수 있다. 이 파일 또한 JDK와 함께 설치되며, 설치한 jdk directory에서 bin directory에서 찾아볼 수 있다. 이때, JVM이 byte code를 컴퓨터가 이해할 수 있는 machine language로 변환을 수행하는데 interpreter와 JIT Compiler 를 활용한 두 가지 방식을 통해 이루어진다.

Java 실행 과정

JIT Compiler

JIT CompilerJust In Time Compiler로, 기존 Interpreter 방식의 단점을 보완하기 위해 도입된 컴파일러다. Java Compiler와 달리, 프로그램을 실행하는 시점에서 컴파일을 수행하며, Java Compiler의 결과는 JVM이 이해 가능한 Byte Code인 것과 달리, JIT Compiler의 결과는 컴퓨터가 이해 가능한 기계어다.

Byte code를 기계어로 매번 변환하는 interpreter 방식보다, compile 과정을 통해 미리 기계어로 변환하여 실행하는 방식이 효율적으로 보일 수 있으나, 컴파일 과정에서 오랜 시간이 소요되기에 자주 사용되지 않을 byte code를 컴파일 하는 것은 비효율적일 수 있다. JIT Compiler는 자주 실행되는 코드를 내부적으로 판단하고 해당 부분을 기계어로 변환하는데, 해당 부분을 Hotspot이라 부른다.

자주 실행되는 부분을 컴파일하여 캐싱하는 방식을 통해 실행 시간을 개선할 수 있지만, 프로그램이 처음 실행되었을 때는 캐싱된 코드가 없기에 지연이 발생할 수 있다. 프로그램의 배포 주기가 긴 경우 큰 문제가 아닐 수도 있으나 배포 주기가 짧아진 최근 상황에서는 큰 문제일 것이다. 이를 해결하기 위한 방법으로 프로그램이 실행되고 배포되기 전 필요한 코드를 실행하도록 하여 기계어가 캐싱된 상태로 프로그램을 배포하는 Warm-up 방식을 고려할 수 있을 것이다.

JIT Compiler와 JVM warm-up에 대해서는 추후 더 자세히 작성해보겠다.

JVM 구조

JVM의 구조는 크게 아래와 같이 구분할 수 있을 것 같다.

  • Class Loader
  • Execution Engine
  • Runtime Data Area

Class loaderjava compiler를 통해 .class 파일로 변환된 class들을 JVM 내부로 적재하는 역할을 수행한다.

Execution engine은 class loader를 통해 JVM에 적재된 byte code를 실행하는 역할을 수행한다. 이 과정에서 byte code기계어로 변환하는 과정이 필요한데, Interpreter와 JIT Compiler가 있다. 또한, JVM의 메모리를 관리하는 GC(Garbage Collector) 또한 execution engine에 포함된다.

마지막으로 Runtime data area는 프로그램이 실행되기 위한 데이터를 위한 메모리 영역으로, JVM OS로 부터 할당 받은 메모리 영역이다. 각 thread별 PC register, Stack(Java, Native)을 가지며, Heap, Method 영역이 존재한다. 특히, Heap 영역은 Eden, Old, Permanent 등의 영역으로 나누어지며, 이는 GC에 의해 관리되는 영역이다.

이들 영역 모두가 하나의 글에 담기는 그 내용이 방대하기에 이 또한 추후에 더 자세히 작성해 보겠다.

JDK, JRE, JVM

Java에 대해 처음 알아볼 때 가장 혼동되는 부분이지 않을까 싶다. 각각은

  • JDK : Java Development Kit
  • JRE : Java Runtime Environment
  • JVM : Java Virtual Machine

에 해당하는 약자이다.

JRE는 Java를 실행하기 위한 환경으로 JVM을 포함하고 있으며, JDK는 Java를 개발하기 위한 도구로, JVM을 포함하는 JRE를 포함한다. JDK 하나만 있으면 된다.
Java를 설치할 때 보통 Oracle JDK, Open JDK, zulu 등 다양한 JDK를 마주하게 되는데, 이는 Oracle이 JDK 유료화를 선언한 후 상업 목적에 비용이 필요한 Oracle JDK와 그렇지 않은 Open JDK로 나누어진다고 생각하면 편할 것 같다.

Open JDKJDKopen source로 구현한 것으로, Azul, Eclipse 등 다양한 벤더에서 이를 구현하고 있으며, Oracle JDK가 아닌 다른 이름의 JDK는 Open JDK에 해당한다 생각하면 될 듯 하다.

다만, 각 벤더 별 JDK를 구현한 방식이 상이할 수 있는데, 이는 JDK에 포함된 JVM 또한 상이할 수 있음을 의미한다. JVM 중에서 Hotspot JVM, J9 JVM이 가장 유명하며, Java를 통해 개발을 하다 보면 언젠간 JVM과 GC 등에 대해 더 자세히 알아야 할 일이 있을 것이기에 본인이 사용하는 JDK가 어떠한 JVM을 기반으로 하는지는 알아두면 좋을지도 모르겠다.

0개의 댓글