OOMKill은 메모리가 부족해서가 아니라 힙 모니터링에 잡히지 않는 off-heap(메타스페이스·스레드 스택·다이렉트 버퍼·코드 캐시)을 계산에 넣지 않아서 발생한다. 힙에 여유가 있어도 프로세스 전체 메모리는 limit을 넘을 수 있다.
쿠버네티스는 JVM 힙이 아니라 컨테이너 프로세스가 실제로 쓰는 RSS 메모리 전체를 감시하고, limit을 넘는 순간 커널이 로그도 없이 프로세스를 즉시 강제 종료한다. 그래서 힙 모니터링만으로는 진짜 메모리 사용량을 알 수 없다.
limit을 넉넉히 올리면 노드 메모리를 과점유해 같은 노드의 다른 POD까지 쫓아낸다. 근본 해결은 limit 상향이 아니라 JVM의 off-heap을 직접 제한하는 것이다.
운영 중인 JVM POD가 하루에 열몇 번씩 재시작되고, kubectl로 확인한 종료 사유는 OOMKill(메모리 초과)이다. 그런데 JVM 힙 모니터링에서는 512M 중 380M만 사용해 여유가 있는 상태다. 모순처럼 보이는 이 현상의 핵심은 관측 주체가 다르다는 점이다.
| 관점 | 보는 메모리 | 판단 |
|---|---|---|
| JVM 힙 모니터링 | 힙 영역만 | 512M 중 380M → 여유 있음 |
| 쿠버네티스/커널 | 컨테이너 프로세스 RSS 전체 |
limit 도달 → 강제 종료 |
쿠버네티스가 감시하는 것은 JVM 힙이 아니라 프로세스가 실제로 점유한 물리 메모리(RSS) 전체다. 힙에 여유가 있어도 off-heap까지 합산되면 컨테이너 limit에 걸리고, limit을 넘는 순간 커널이 프로세스를 즉시 강제 종료한다.
limit 512M 중 사용량 380M → 힙만 보면 약 132M 여유.RSS가 컨테이너 메모리 limit에 도달 → 커널이 즉시 강제 종료(OOMKill).
(보충: 영상은 힙 512M/380M 수치만 제시했고, off-heap 사용량과 컨테이너 limit의 구체 수치는 밝히지 않았다.)JVM 프로세스가 쓰는 메모리는 힙만이 아니다. 힙 외에도 여러 off-heap 영역이 있고, 이것들은 힙 모니터링에 전혀 잡히지 않는다. 그래서 힙 지표만 보면 이 메모리들이 통째로 시야에서 사라진다.
| off-heap 영역 | 대략적인 용도 (보충) |
|---|---|
메타스페이스(Metaspace) |
로드된 클래스 메타데이터 저장 |
| 스레드 스택(thread stack) | 스레드마다 할당되는 호출 스택 |
| 다이렉트 버퍼(direct buffer) | 힙 밖 네이티브 I/O 버퍼 |
| 코드 캐시(code cache) | JIT가 컴파일한 네이티브 코드 |
(보충: 각 영역의 '용도' 열은 일반 지식으로 채운 것이며, 영상은 네 영역의 이름만 열거했다.)
off-heap까지 합쳐 limit에 걸린다면, 단순히 limit을 2GB, 3GB로 넉넉히 올리면 되지 않을까? 화자는 이것이 근본 해결이 아니라 문제를 노드 전체로 전가하는 행위라고 짚는다.
limit을 과하게 잡으면 해당 POD가 노드의 메모리를 과다 점유하고, 한 POD의 메모리 급증이 같은 노드에 있는 다른 POD까지 쫓아낸다(eviction). 즉 한 컨테이너의 튜닝 실패가 이웃 컨테이너의 장애로 번진다.
그래서 JVM 환경에서의 정답은 limit을 키우는 것이 아니라 off-heap을 직접 제한하는 것이다. (보충: 실무에서는 -XX:MaxMetaspaceSize, -XX:MaxDirectMemorySize 등으로 off-heap 상한을 명시하는데, 영상은 구체 옵션명까지는 제시하지 않았다.)
limit 상향과 off-heap 직접 제한은 방향이 반대다. limit을 올리는 것은 문제를 노드로 떠넘기는 회피이고, off-heap을 직접 제한하는 것만이 프로세스 안에서 원인을 통제하는 해법이다.화자는 마지막으로 OOMKill의 본질을 다시 정의한다. OOMKill은 메모리가 부족해서 생기는 게 아니라, 보이지 않는 메모리를 계산에 넣지 않아서 생긴다. 힙 모니터링만으로는 컨테이너의 진짜 메모리 사용량을 알 수 없다는 것이 이 사례가 남기는 교훈이다.
또한 커널의 강제 종료는 애플리케이션 로그를 남기지 않고 프로세스를 즉시 죽이기 때문에, 원인을 사후에 로그로 추적하기 어렵다는 점도 함께 기억할 만하다.