쿠버네티스(Kubernetes) 환경에서 자바(Java) 버추얼 머신(JVM) 기반 애플리케이션을 안정적으로 운영하려면 CPU와 메모리 자원 할당에 대한 깊이 있는 이해가 필수적입니다. 단순히 자원 요청(Request)과 제한(Limit) 값을 설정하는 것을 넘어, JVM 내부 동작 방식과 쿠버네티스 컨테이너의 자원 관리 메커니즘 간의 상호작용을 고려해야 합니다. 잘못된 설정은 예측 불가능한 메모리 부족(OOMKilled)이나 성능 저하로 이어질 수 있습니다.
JVM 컨테이너에는 힙(Heap) 경계와 컨테이너 경계라는 두 가지 다른 메모리 한계가 존재합니다. -Xmx 옵션은 JVM 힙의 최대 크기를 지정하지만, 컨테이너 메모리 제한(limits.memory)은 힙뿐만 아니라 메타스페이스(Metaspace), 코드 캐시(Code Cache), 스레드 스택(Thread Stack), 다이렉트 버퍼(Direct Buffer) 등 모든 JVM 외부 메모리 영역을 포함합니다. 따라서 -Xmx를 컨테이너 메모리 제한과 동일하게 설정하면 힙 외부 영역이 사용할 공간이 부족해져 JVM 힙 OOM(OutOfMemoryError)이 발생하기 전에 컨테이너 전체가 OOMKilled될 위험이 커집니다. 일반적으로 최대 힙 크기는 컨테이너 메모리의 50~75% 수준에서 시작하여 실제 워크로드로 검증하는 것이 권장됩니다. 또한, CPU 제한(CPU Limit)은 JVM이 인식하는 프로세서 수에 영향을 미쳐 가비지 컬렉터(GC) 구성이나 포크조인풀(ForkJoinPool) 병렬성 등 JVM 내부 동작 방식까지 변경할 수 있습니다. 낮은 CPU 제한과 지속적인 스로틀링(throttling)은 GC 일시정지(Pause) 시간을 늘려 애플리케이션의 응답 지연(p99 latency)을 악화시킬 수 있습니다.
이러한 복잡성을 고려할 때, 하나의 권장 비율이나 설정값을 맹신하기보다는 실제 트래픽 환경에서 라이브 힙(Live Heap), 오프-힙(Off-heap) 메모리, 컨테이너 메모리 사용량, CPU 스로틀링, GC 일시정지 시간 등을 종합적으로 측정하고 분석하는 것이 중요합니다. 예를 들어, 4GiB의 자바 힙을 사용하려면 컨테이너 메모리는 4GiB보다 훨씬 커야 하며, 75%의 힙 비율을 적용한다면 약 5.33GiB 이상의 컨테이너 메모리가 필요합니다. JVM의 MaxRAMPercentage 옵션은 쿠버네티스의 메모리 요청(Memory Request)이 아닌 메모리 제한(Memory Limit)을 기준으로 힙 크기를 계산하므로 이 점을 명확히 인지해야 합니다. 운영 환경에서는 JVM 내부 지표(힙 사용량, GC 통계)와 컨테이너 지표(전체 메모리, RSS, CPU 사용량, 스로틀링)를 동일한 시간 축으로 수집하여 메모리 증가 원인(라이브 힙, 다이렉트 버퍼, 스레드 스택 등)을 정확히 파악하고 적절하게 대응해야 합니다. 이를 통해 쿠버네티스 환경에서 자바 애플리케이션의 안정성과 성능을 극대화할 수 있습니다.