Kubernetes에서 Java JVM의 CPU·메모리 Request와 Limit

1 hour ago 2

TL;DR JVM 컨테이너에는 Heap 경계와 Container 경계라는 서로 다른 두 개의 메모리 한계가 존재 -Xmx를 limits.memory와 같게 설정하면 Heap 외부 영역이 사용할 공간이 없어져 OOMKilled될 가능성이 높음 Memory Request는 Heap 계산 기준이 아니며, MaxRAMPercentage는 기본적으로 Memory Limit을 기준으로 동작 CPU Limit은 JVM이 인식하는 프로세서 수, 기본 GC, GC Worker와 ForkJoinPool 구성에 영향을 줌 낮은 CPU Limit과 지속적인 throttling은 GC Pause와 p99 latency를 악화시킬 수 있음 하나의 권장 비율을 맹신하기보다 Live Heap, Off-heap, 컨테이너 메모리, CPU throttling, GC Pause를 실제 트래픽에서 함께 측정해야 함 4GiB의 Java Heap을 사용하려면 컨테이너 메모리는 4GiB보다 커야 함 Kubernetes의 limits.memory는 Heap뿐 아니라 Metaspace, Code Cache, Thread Stack, Direct Buffer, GC 자료구조, 네이티브 메모리 등을 모두 포함 -Xmx를 컨테이너 메모리 Limit과 동일하게 설정하면 JVM Heap OOM보다 먼저 컨테이너가 OOMKilled될 수 있음 JVM에서 발생하는 메모리 부족은 크게 두 종류 JVM Heap OOM: Heap 내부 공간이 부족해 OutOfMemoryError 발생 Container OOM: 컨테이너 전체 메모리가 Limit에 도달해 Linux 커널이 JVM을 SIGKILL Container OOM은 JVM이 오류 로그나 Heap Dump를 남기기도 전에 종료될 수 있으며, 일반적으로 ExitCode 137로 표시됨 컨테이너 메모리는 다음 영역이 함께 사용 Java Heap Metaspace JIT Code Cache 플랫폼 스레드의 Native Stack NIO·Netty·gRPC 등의 Direct Buffer GC 내부 자료구조 JNI 및 Native Library 파일 캐시, 소켓 버퍼 등 컨테이너에 청구되는 기타 메모리 최대 Heap은 컨테이너 메모리의 50~75% 정도에서 시작하고 실제 워크로드로 검증하는 것이 일반적인 접근 256MiB 컨테이너에서 -Xmx256m을 사용하면 Heap 외부 메모리가 부족해져 OOMKilled될 가능성이 큼 -X...

Read Entire Article