Skip to content

Latest commit

 

History

History
80 lines (42 loc) · 4.79 KB

graal_memory.md

File metadata and controls

80 lines (42 loc) · 4.79 KB

네이티브 이미지의 메모리 최적화

오늘은 네이티브 이미지의 메모리 최적화 기법을 알아보겠다.

네이티브 이미지를 복습하자면 네이티브 이미지는 자바코드를 미리 ahead of time 컴파일 하는 기술이다. 즉 바로 바이너리로 변환하는 기법으로 JVM없이 자바 코드를 실행시킬 수 있는 것이다.

네이티브 이미지의 메모리 최적화

  • Profile-Guided Optimizations (PGO)는 추가적인 성능 향상과 높은 처리량을 제공한다.
  • 적절한 GC를 선택하고, 가비지 수집 정책을 수정하면 GC 시간을 줄일 수 있다.
  • 이미지 빌드 중에 애플리케이션 구성을 로드하면 애플리케이션 시작 속도를 높일 수 있다.

메모리 관리

네이티브 이미지는 실행될 때 Hotspot VM에서 실행되는 것이 아니라 GraalVM의 런타임 시스템에서 실행된다. 그리고 런타임시에 생겨나는 자바 객체는 힙 영역에 할당된다.

힙은 네이티브 이미지가 초기에 실행될 때 할당되며 실행되는 동안 늘어나거나 줄어들 수 있다.

힙이 가득차면 가비지 컬렉터가 트리거되어 사용되지 않는 객체를 메모리에서 회수합니다.

그리고 자바 힙 관리를 위해 Native Image는 여러 GC를 제공하고 있어요

  • Serial GC
  • G1 GC
  • Epsilon GC

Serial GC

native-image --gc=serial HelloWorld serial gc를 사용하는 예시에요

serial은 기본으로 제공되는 gc라서 명시하지 않으면 자동으로 serial gc로 할당됩니다.

만약 자바의 최대 힙 크기를 제공하지 않으면 네이티브 이미지에서는 힙 크기를 실제 메모리 크기의 80% 양으로 설정합니다.(이 설정은 최댓값일 뿐이고 실제 자바 프로그램에서는 더 적게 사용할 수 있음)

여기서 알아둬야할게 GC를 사용할때는 추가 메모리 공간이 필요하다는 것이다. 경우에 따라 최대 힙 메모리의 두배의 공간이 필요할 수 도 있습니다.

따라서 RSS(Resident Sent Size)가 일시적으로 증가할 수 있습니다.

그렇다면 메모리제약이 있는 환경(컨테이너 등)에서는 문제가 발생할 수 있으니 튜닝을 잘 해야합니다.

튜닝에 관련해서는 다음에 알아볼게요

G1 GC

GraalVM은 Hotspot VM의 G1 GC를 기반으로 G1 GC를 제공하고 있습니다.

현재 G1 GC는 AMD64용 Linux에서 빌드된 네이티브 이미지에서만 사용할 수 있으며, 이를 활성화하려면 --gc=G1 옵션을 전달해야합니다.

`native-image --gc=G1 HelloWorld

만약 자바 최대 힙 크기를 지정하지 않으면 G1 GC를 사용하는 네이티브 이미지의 힙은 메모리 공간의 25%를 크기로 지정합니다.

클래스 초기화

일반적인 JVM의 자바 애플리케이션은 클래스에 처음 접근될 때 초기화가 되어야합니다.

따라서 클래스를 초기에 전부 초기화는 자바 애플리케이션을 미리 AoT 하는데에는 �부정적인 영향이 있습니다.

  • 네이티브의 실행 파일의 성능을 크게 저하시킵니다. 클래스의 필드 또는 메서드에 접근할때마다 초기화 되었는지 확인해야하고, 최적화하지 않으면 성능이 크게 저하됩니다.
  • 애플리케이션을 시작하는데 필요한 연산량과 시간이 늘어난다. 예를 들어 간단한 Hello World 애플리케이션의 경우 300개 이상의 클래스를 초기화해야 한다.

클래스 초기화의 부정적인 영향을 줄이기 위해서 네이티브 이미지는 빌드 시에 클래스 초기화를 지원하고 있습니다.

실행 파일을 빌드할 때 클래스를 초기화하여 런타임 초기화 및 검사를 불필요하게 만들 수 있습니다.

초기화된 클래스의 모든 정적인 상태는 실행 파일에 저장됩니다.

빌드 시점에 초기화된 클래스의 정적 필드에 대한 엑세스는 애플리케이션에 투명하게 표시되며 런타임에 초기화된 것처럼 작동합니다.

이러한 자바 클래스의 초기화를 복잡하게 만드는 여러가지 정책들이 있는데, 네이티브 이미지는 아래의 두 가지를 통해 이를 해결합니다.

  • 빌드 타임 초기화
  • 안전한 클래스들만 자동 초기화

+ GraalVM와 네이티브 이미지를 리서치하게 된 배경에는 급증하는 트래픽을 대응하기 위한 빠른 스타트와 컨테이너 환경 기반의 인프라스트럭처 구성등이 있지만, GraalVM은 완전히 최적화된 JIT 컴파일러보다는 성능이 떨어집니다.

그리고 커뮤니티 버전에 경우에는 Serial GC밖에 사용할 수 없습니다. 그래서 기존의 JIT 컴파일러를 이용하는 방식과 이를 웜업을 준비하는 방향으로 작업을 진행하게 되었습니다.