..

jvm young generation

Overview


지난 포스트에서 JVM의 전반적인 메모리 구조(Heap, Stack, Metaspace)를 다뤘었고, 이번 포스트에서는 가비지 컬렉션(GC)의 주 무대이자 성능 최적화의 핵심인 Heap의 상세 구조에 대해 다룬다.

Heap 영역이 중요한 이유는 GC(Garbage Collector)가 대부분의 시간을 이곳에서 보냄으로써 메모리를 관리하기 때문이다. 서버 지연의 상당 부분이 이 영역의 관리 방식에서 비롯되며, 그중에서도 객체가 처음 생성되는 앞마당인 Young Generation을 이해하는 것이 우선.

Young 영역의 구조


Heap은 크게 Young(신입) 영역과 Old(고인물) 영역으로 나뉘며, Young 영역은 다시 세 개의 구역으로 세분화된다.

  • Eden (신생아실): new 키워드로 생성된 객체가 가장 먼저 할당되는곳으로 대다수의 객체는 생성 후 곧바로 참조가 끊겨 여기서 생을 마감한다.
  • Survivor 0 / 1 (생존자 대기실): Eden에서 살아남은 객체들이 임시로 머무는 공간이다. 두 개의 영역 중 반드시 한 곳은 비어있는 상태를 유지하는 것이 특징이다.

한 줄 요약: 객체가 태어나면 Eden, 한 번이라도 생존하면 Survivor로 이동한다.

Minor GC 동작 방식


Eden 영역이 가득 차면 Minor GC가 발생하여 청소를 시작한다.

  1. 생존 체크: Eden과 현재 사용 중인 Survivor 영역(예: S0)을 탐색하여 여전히 참조되고 있는 ‘살아있는’ 객체를 선별
  2. 복사 및 이동 (Copying): 선별된 객체들을 비어있는 다른 Survivor 영역(예: S1)으로 한꺼번에 옮긴다.
  3. 나이 측정 (Aging): 객체가 이동할 때마다 헤더에 있는 객체 나이(Age) 값을 1씩 증가시킨다.
  4. 대량 삭제: 이동이 확인된 후, 기존 Eden과 이전 Survivor 영역에 남은 객체들을 통째로 삭제한다.

중요: Survivor 0과 1 중 한 곳은 반드시 비어 있어야 함. 이는 메모리 파편화(Fragmentation)를 방지하기 위한 정교한 전략

Promotion (승격)


Survivor 영역 사이를 오가며 끈질기게 살아남아 설정된 임계치(기본값 15세)에 도달한 객체들은 큰 결정을 맞이한다.

“이 객체는 장기 생존할 가능성이 높으니, 더 큰 공간인 Old 영역으로 옮기자.”

이 과정을 Promotion(승격)이라고 부른다. 오래 살아남을 객체들을 따로 관리함으로써 GC의 효율성을 극대화하려는 전략이다.

실무에서의 성능 이슈


이 영역의 설정이 적절하지 못하면 서비스 운영에 치명적인 영향을 줄 수 있음

  • Eden 영역이 너무 작을 경우: GC가 빈번하게 발생하여 애플리케이션의 처리 성능이 저하된다. (Stop-The-World 빈도 증가)
  • Survivor 영역이 너무 작을 경우: 아직 젊은 객체들이 자리가 부족해 Old 영역으로 조기 승격(Premature Promotion)된다. 이는 결과적으로 무거운 Major GC(Full GC)를 앞당겨 서버 멈춤 현상을 유발한다.

요약


  • 모든 객체는 Eden에서 태어나며, Minor GC를 통해 생존 여부를 검증받는다.
  • 생존한 객체는 Survivor 영역을 번갈아 이동하며 나이(Age)를 먹으며,
  • 일정 나이가 되면 Old 영역으로 승격된다. 그리고 해당 전체과정의 밸런스가 서버 안정성의 핵심이다.