HotSpot JVM

Lenny Lee
6 min readNov 22, 2020

--

원래는 Quarkus에 대해 써 볼까 했는데, 이 이야기를 하려면 GraalVM 이야기를 해야 하고, 결국 JVM 이야기를 안할 수 없어 HotSpot 이야기를 먼저 해 보도록 하겠습니다.

HotSpot은 현재 사용되는 JVM 중 가장 일반적으로 쓰이는 VM입니다. 로컬에 설치된 Java 버전을 확인해 보면 대충 아래와 비슷한 결과가 나올 겁니다.

> java -versionjava version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

Java Virtual Machine

Java는 1990년대 썬 마이크로시스템즈Sun Microsystems의 제임스 고슬링James Gosling 할배가 개발한 이후 현재 가장 널리 사용되는 프로그램 언어입니다. Java는 처음 개발될 때부터 자신만의 철학을 가지고 있는데, 이는 아래의 다섯가지 원칙에서 잘 드러나 있습니다.

1. It must be simple, object-oriented, and familiar.
2. It must be robust and secure.
3. It must be architecture-neutral and portable.
4. It must execute with high performance.
5. It must be interpreted, threaded, and dynamic.

— 1.2 Design Goals of the Java TM Programming Language, Introduction to Java TM Technology, Oracle

이 중 3번의 중립적 아키텍처architecture-neutral와 이식성portable은 쉽게 말해 서로 다른 환경에서도 동일하게 실행 가능해야 한다는 것인데, 이를 위한 기술이 Java Virtual Machine, 즉 JVM입니다.

The architecture-neutral and portable language platform of Java technology is known as the Java virtual machine.

— 1.2.3 Architecture Neutral and Portable, Introduction to Java TM Technology, Oracle

기본적으로 프로그램은 CPU가 이해할 수 있는 기계어로 컴파일되어 실행됩니다. 이 때문에 C/C++의 경우 특정 CPU 환경에서 컴파일된 실행 파일은 다른 CPU 환경에서 실행될 수가 없게 되며, 바꿔 말하면 n개의 다른 플랫폼에서 실행시키려면 n개의 실행 파일을 제공해야 한다는 얘기가 되겠죠.

Java 다운로드 페이지이지만, 대충 이런 느낌?

Java는 이 역할을 JVM이 대신합니다. Java 컴파일러는 기계어로 된 실행파일 대신 바이트코드bytecode를 생성하고, JVM이 바이트코드를 해석하여 프로그램을 실행시키게 됩니다. 어떤 플랫폼이라도 이에 대응하는 JVM만 설치되어 있으면, 하나의 Java 바이트코드로 어떤 환경에서도 실행이 가능하단 이야기입니다.

JVM의 구조

JVM를 간단히 나누면 다음 세 부분으로 표현할 수 있습니다.

  • Class Loader : 바이트코드로 표현된 클래스를 JVM 안으로 로딩하고 Runtime Data Area로 이를 배치합니다.
  • Execution Engine : 로딩된 클래스의 바이트코드를 해석하여 실행합니다.
  • Runtime Data Area : Java 프로그램을 실행시키기 위해 OS로부터 배정받은 메모리 공간입니다.

프로그램이 실행되면 Execution Engine이 바이트코드를 명령어 단위로 읽고 의미를 해석하여 실행시킵니다. 이 때도 크게 두 가지의 실행 방법이 있습니다.

  • Interpreter : 바이트코드의 명령어를 순차적으로 읽고 실행합니다. JVM 초기부터 도입된 방식이며, 같은 코드를 여러 번 실행하는 경우에도 매번 똑같이 명령어를 읽고 실행해야 하기 때문에 효율성이 떨어집니다.
  • JIT(Just In Time) Compiler : Interpreter의 약점을 보완하기 위해 나온 방법입니다. 처음에는 Interpreter 방식으로 동작하다가 어느 시점에 바이트코드를 네이티브 코드로 컴파일하여 실행 속도를 향상 시킵니다.

그럼 처음부터 JIT Compiler로 컴파일해서 동작시키면 될 것 아냐? 라고 생각할 수 있겠지만, 바이트코드를 컴파일하는 데에도 CPU와 메모리 자원이 필요합니다. 이는 프로그램의 실행 속도를 떨어뜨리는 원인이 되므로, 결국 JIT Compiler를 얼마나 최적화된 방식으로 사용하느냐가 JVM 성능에 영향을 주게 됩니다.

HotSpot JVM

HotSpot JVM은 롱뷰테크놀로지Longview Technologies의 기술을 기반으로 하고 있습니다. 1997년 썬 마이크로시스템즈는 롱뷰를 인수하였고 이들의 기술을 기반으로 JIT Compiler를 최적화된 방식으로 다시 구현하는 프로젝트에 착수했습니다. 1999년 썬은 HotSpot JVM을 출시했고 2000년 출시된 Java 1.3부터 기본 JVM으로 채택하였습니다.

HotSpot은 이름 그대로 프로그램 내에서 내부적으로 프로파일링하여 핫스팟을 찾고 그 부분만 JIT Compiler로 네이티브 코드로 변환하는 방법을 사용합니다. HotSpot은 클라이언트 버전과 서버 버전으로 나뉘는데 각각의 특징은 다음과 같습니다.

  • 클라이언트 버전 : 주로 프로그램의 시작 시간 최소화에 관심이 있습니다. 부분 최적화를 통해 특정 부분의 속도를 빠르게 하며 전체적인 최적화는 보장되지 않습니다.
  • 서버 버전 : 부분 코드 실행보다는 전체적인 프로그램 최적화에 관심이 있습니다. 시작 시간을 희생하더라도 코드 전체적인 최적화를 진행하게 됩니다.

64비트 이상의 운영체제에서는 서버 버전이 기본으로 채택되며, 요즘 사용되는 시스템에서 클라이언트 버전은 큰 의미가 없다고 할 수 있겠습니다. 아래는 로컬 맥북에서 java 를 실행시킨 결과로, 자동적으로 HotSpot 서버 버전이 사용되고 있음을 알 수 있습니다.

> java사용법: java [-options] class [args...]
(클래스 실행)
또는 java [-options] -jar jarfile [args...]
(jar 파일 실행)
여기서 options는 다음과 같습니다.
-d32 사용 가능한 경우 32비트 데이터 모델을 사용합니다.
-d64 사용 가능한 경우 64비트 데이터 모델을 사용합니다.
-server "server" VM을 선택합니다.
기본 VM은 server입니다.,
서버급 시스템에서 실행 중이기 때문입니다.

References

--

--

No responses yet