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를 운영에서 조심해야 하는 이유는 무엇인가?
    • 파일이 크고 개인정보나 토큰 같은 객체 내용이 포함될 수 있기 때문이다.