Memory Stack Heap Virtual Memory
3줄 요약
- Java 메모리는 stack, heap, metaspace, direct/native memory, OS virtual memory를 함께 봐야 한다.
- OOM은 heap 부족만 뜻하지 않으며 native memory, thread stack, direct buffer, container limit에서도 발생할 수 있다.
- 메모리 장애 분석은 heap 사용량, GC, RSS, swap, dump를 같은 시간축에 놓고 봐야 한다.
핵심 정리
- Stack은 thread별 호출 프레임이고 heap은 Java 객체가 저장되는 공유 영역이다.
- Virtual memory와 paging은 process가 보는 주소 공간과 실제 물리 memory 사이의 계층을 만든다.
- Memory leak은 더 이상 필요 없는 객체나 native 자원을 계속 참조해 회수되지 않는 상태다.
- GC는 heap을 회수하지만 pause와 CPU 비용을 만들 수 있고, leak이 있으면 GC가 자주 돌아도 해결되지 않는다.
- Heap dump는 강력하지만 크고 민감한 정보를 포함할 수 있어 운영에서 수집 위치와 보관 정책이 필요하다.
헷갈리는 지점
- Java는 GC가 있으니 memory leak이 없다고 오해하기 쉽다.
- GC는 도달 불가능한 객체를 회수할 뿐, 계속 참조되는 객체는 회수하지 못한다.
- Cache, static collection, ThreadLocal, listener 등록 누락이 leak 원인이 될 수 있다.
- Heap 사용량과 process RSS를 같은 값으로 보기 쉽다.
- RSS에는 heap 외에도 metaspace, thread stack, direct buffer, native library memory가 포함된다.
- 컨테이너에서는 cgroup limit까지 함께 봐야 한다.
- Swap은 memory 부족을 해결한다고 생각하기 쉽다.
- 서버 애플리케이션에서 swap은 극심한 지연을 만들 수 있다.
- Swap 발생은 memory pressure 신호로 보고 원인을 줄여야 한다.
확인 질문
- Stack과 heap의 가장 중요한 차이는 무엇인가?
- Stack은 thread별 호출 흐름이고 heap은 객체가 저장되는 process 공유 영역이다.
- OOM이 heap 문제인지 확인하려면 무엇을 봐야 하는가?
- OOM 메시지, heap 사용량, GC log, RSS, native memory, container limit을 함께 봐야 한다.
- Heap dump를 운영에서 조심해야 하는 이유는 무엇인가?
- 파일이 크고 개인정보나 토큰 같은 객체 내용이 포함될 수 있기 때문이다.