최근 JDK 8에서 JDK 17로 업그레이드하는 과정에서 애플리케이션의 메모리 사용량이 급격히 증가하는 현상이 발생했고, 결국 Kubernetes의 Pod가 OOMKilled 상태로 종료되는 문제가 발생했습니다.
처음에는 자바(Java) 애플리케이션에서 흔히 겪는 Heap 메모리 부족이나 GC 문제일 것으로 예상했습니다. 하지만 로그를 분석해 보니, 예상과는 다르게 JVM Heap이 아닌 외부에서 메모리 문제가 발생하고 있었습니다. 저에게는 다소 낯설고 새로운 유형의 문제였죠.
이 문제를 분석하며 알게 된 중요한 환경 변수 중 하나가 바로 MALLOC_ARENA_MAX
였습니다. 이 글에서는 제가 해당 옵션을 이해하기 위해 정리했던 배경지식과 개념들을 적어보려합니다.
Java를 공부하다보면 흔히 접하는 개념 중 하나가 바로 JVM의 Heap 메모리입니다. 하지만 Java 애플리케이션은 Heap 외에도 다양한 메모리 영역을 사용합니다. 그 중 Native Memory에 대해 알면 앞서 이야기했던 MALLOC_ARENA_MAX
를 더 잘 이해할 수 있어 이것부터 정리해보겠습니다.
Java 애플리케이션은 Heap 외에도 Native Memory라는 영역을 사용합니다. Native Memory는 JVM이 직접 관리하지 않고 OS에서 관리하는 메모리인데요. 즉, JVM 바깥의 메모리 영역을 의미합니다.
이러한 Native Memory는 다음과 같은 상황에서 사용됩니다.