코드 저장소.

GraalVM? 본문

Java

GraalVM?

slown 2025. 8. 5. 15:34

목차

1.GraalVM?

2.기존의 JVM과의 작동 차이점

 

1.GraalVM?

GraalVM은 사전 네이티브 이미지 컴파일 기능을 갖춘 고급 JDK입니다. 그리고 단순히 새로운 JVM이 아니라, 여러 언어(Java, JavaScript, Python 등)를 실행할 수 있는 멀티랭귀지 실행 환경이기도 합니다. GraalVM의 주요 이점은 공식 사이트에서 아래와 같이 적혀 있습니다. 

 

낮은 리소스 사용량 : GraalVM에서 사전 컴파일된 Java 애플리케이션은 실행에 필요한 메모리와 CPU 사용량이 적습니다. JIT(Just-In-Time) 컴파일에는 메모리와 CPU 사이클이 소모되지 않습니다. 결과적으로 애플리케이션 실행에 필요한 리소스가 줄어들고 대규모 운영 비용도 절감됩니다.

 

빠른 시작 : GraalVM을 사용하면 런타임이 아닌 빌드 시간에 애플리케이션의 일부를 초기화하여 Java 애플리케이션을 더 빠르게 시작하고, 워밍업 없이 예측 가능한 최대 성능을 즉시 달성할 수 있습니다.

 

컴팩트 패키징 : GraalVM에서 사전에 컴파일된 Java 애플리케이션은 크기가 작아 빠르고 효율적인 배포를 위해 가벼운 컨테이너 이미지로 쉽게 패키징할 수 있습니다.

 

향상된 보안 : GraalVM은 도달할 수 없는 코드(사용되지 않는 클래스, 메서드 및 필드), JIT(Just-In-Time) 컴파일 인프라, 빌드 타임에 초기화된 코드를 제외하여 Java 애플리케이션의 공격 표면을 줄입니다. GraalVM의 폐쇄형 환경 가정은 런타임에 리플렉션, 직렬화 등의 동적 기능을 비활성화하여 애플리케이션이 알 수 없는 코드를 로드하는 것을 방지하며, 빌드 타임에 이러한 클래스, 메서드 및 필드의 명시적인 포함 목록을 요구합니다. GraalVM은 바이너리에 소프트웨어 자재 명세서(SBOM)를 내장하여 일반적인 보안 스캐너를 사용하여 Java 애플리케이션의 공개된 CVE(Common Vulnerabilities and Exposures)를 더 쉽게 확인할 수 있도록 합니다.

 

클라우드 네이티브 마이크로서비스를 쉽게 구축 : Micronaut, Spring Boot, Helidon, Quarkus와 같은 인기 마이크로서비스 프레임워크와 Oracle Cloud Infrastructure(OCI), Amazon Web Services(AWS), Google Cloud Platform(GCP), Microsoft Azure와 같은 클라우드 플랫폼은 모두 GraalVM을 지원합니다. 이를 통해 바이너리로 컴파일되고, 소형 컨테이너로 패키징되어 가장 널리 사용되는 클라우드 플랫폼에서 실행되는 클라우드 네이티브 Java 마이크로서비스를 쉽게 구축할 수 있습니다.

 

Python 및 기타 언어로 Java 애플리케이션 확장 : GraalVM을 사용하면 Python, JavaScript 등의 언어를 내장하여 Java 애플리케이션을 확장할 수 있습니다.


기존 개발 및 모니터링 도구 사용 : 기존 Java 애플리케이션 개발 및 모니터링 도구는 GraalVM 애플리케이션 바이너리와 호환됩니다. GraalVM은 Maven 및 Gradle용 빌드 플러그인과 CI/CD용 GitHub Actions를 제공합니다. GraalVM은 Java Flight Recorder(JFR), Java Management Extensions(JMX), 힙 덤프, VisualVM 및 기타 모니터링 도구를 지원합니다. GraalVM은 기존 Java 편집기/IDE 및 JUnit과 같은 단위 테스트 프레임워크와도 호환됩니다.

 

2.기존의 JVM과의 작동 차이점

그럼 GraalVM이 나오게 된 것에는 Java에서 사용하는 JVM을 알아야합니다. 우선 JVM은 자바 가상머신으로 플랫폼 독립성을 목표로 등장했다. 이를 위해 JVM(Java Virtual Machine)이라는 추상 계층이 설계되었고, Java 소스는 바이트코드로 변환되어 JVM 위에서 실행된다.하지만 이러한 컨셉에도 단점이 있다면 실행을 하는 속도가 느리다는 단점이 있었습니다. 그래서 이러한 단점을 해소를 하기 위해서 Java 1.3부터 JIT(Just-In-Time)를 도입을 하게 됩니다. 

 

2-1. Jit 컴파일러

jit 컴파일러

JIT 컴파일러는 실행 중에 자주 쓰이는 코드를 JVM이 자동으로 기계어로 변환을 하고 JVM 내부 캐시에 남겨서 다음에는 더 빠르게 실행을 하는 컴파일러 방식으로 기존의 JVM보다는 훨씬 더 빠른 속도를 이룰 수 있었습니다. 하지만 이방식도 단점은 존재를 합니다.

  • 최초 실행 시에는 인터프리터로 시작 → 실행 속도 느림
  • 컨테이너/서버리스 환경에서 cold start latency(시작 지연) 심각

이러한 단점을 해소를 하기 위해 나온 것이 AOT입니다. 

 

2-2.AOT 컴파일러

 

Java의 AOT 컴파일러

 

AOT(선행 컴파일, Ahead-Of-Time Compile)는 프로그램 실행 전에(빌드 타임에) 코드를 미리 운영체제별 네이티브 실행 파일로 변환하는 방식을 의미합니다. 간단히 이야기를 하면 애플리케이션이 실행이 되면 JVM/JIT 없이 곧바로 OS에서 실행 파일로 동작이 되므로 기동 속도가 매우 빠르고, 메모리도 훨씬 적게 사용을 하게 됩니다. 

 

GraalVM Native Image의 AOT 컴파일 방식 동작 과정

  1. 정적 분석(Reachability Analysis)
    • GraalVM의 Native Image 빌더는, Java 바이트코드(.class)와 의존성 라이브러리 전체를 분석해서 엔트리포인트(main 메서드)부터, 실제로 실행될 가능성이 있는 모든 클래스/메서드/리소스를 추적합니다.
    • 이 과정에서 “실제로 한 번도 호출되지 않는(dead code)”는 아예 바이너리에서 제외됩니다.
    • 결과적으로 실행 파일 크기가 줄고, 불필요한 코드가 사라져 보안성도 좋아집니다.
  2. 네이티브 실행 파일로 컴파일
    • 분석이 끝나면, 실제로 쓰이는 코드/리소스만 OS별 네이티브 실행 파일(.exe, ELF 등)로 변환합니다.
    • 이 때, 기존 JVM/JRE는 전혀 필요 없고, SubstrateVM(최소한의 Java 런타임)만 포함됩니다.
  3. 동적 기능(리플렉션, 프록시 등) 명시적 등록 필요
    • Java는 리플렉션, 프록시, 동적 클래스 로딩 같은 “런타임 동적 기능”을 많이 사용합니다.
    • AOT 방식에서는 이런 기능을 빌드 시점에 반드시 명시적으로 등록해야만
      실행 파일에 포함됩니다.
    • 등록하지 않으면, 런타임에 “ClassNotFoundException”, “NoSuchMethodError” 등 에러가 발생합니다.

2-3. AOT(GraalVM Native Image)의 장단점

 

장점

  • 빠른 기동 속도: cold start latency가 거의 없음. 서버리스/Lambda에 최적
  • 낮은 메모리 사용량: JIT, JVM 메타데이터 등이 빠져서 메모리 footprint 최소화
  • 경량/배포 편의: 실행 파일 하나만 있으면 JVM/JRE 필요 없이 바로 배포/실행 가능
  • 보안성 강화: dead code 완전 제거, 공격 표면 최소화

단점/제약

  • 빌드 시간: 전체 코드 정적 분석/이미지 생성 때문에 빌드 시간이 오래 걸림
  • 동적 기능 제약: 리플렉션/프록시/동적 로딩 등은 빌드 시점 등록 필수
  • 프레임워크/라이브러리 호환성: Spring, Hibernate 등 일부 프레임워크는 추가 설정 필요
  • 런타임 유연성 감소: Agent, Java Instrumentation, 동적 클래스 생성 등은 대부분 미지원

 

 

참고

https://www.graalvm.org/latest/introduction/

 

Introduction

 

www.graalvm.org

https://deeplify.dev/back-end/java/graalVM#jit-vs-aot

 

[Java] GraalVM 이란?

Oracle GraalVM에 대해서 알아보고, 장단점을 자세하게 알아봅시다.

deeplify.dev