2 분 소요

자바 힙 메모리(Heap Memory)new 키워드로 생성된 객체‧배열이 저장되는 공간이며, 가비지 컬렉션(Garbage Collection) 으로 자동 관리됩니다. 힙 구조를 깊이 이해하면 OutOfMemoryError 예방과 GC 튜닝으로 성능을 끌어올릴 수 있습니다.


힙 메모리란?

힙은 JVM이 확보한 공유 메모리로, 모든 스레드가 동시 접근할 수 있습니다.

객체가 더 이상 참조되지 않으면 가비지 컬렉터가 회수해 메모리 누수를 방지합니다.


힙 메모리 3-계층 구조

영역 주요 내용 GC 종류 특징
Young Generation 생성된 지 얼마 안 된 객체 Minor GC 짧은 수명, Eden + Survivor(S0/S1)
Old Generation 여러 번 Minor GC를 살아남은 장수 객체 Major / Full GC 길고 큰 객체, GC 빈도 낮지만 Pause 길음
Metaspace(JDK 8+) 클래스 메타데이터, 상수 풀 클래스 Unload 시 힙 외부 네이티브 메모리 사용

1. Young Generation

  • Eden – 객체가 처음 놓이는 공간
  • Survivor S0/S1 – Eden에서 살아남은 객체가 ping-pong 방식으로 이동
  • Minor GC 가 빈번해 짧은 Stop-The-World 를 유발하지만 속도가 빠릅니다.

2. Old Generation

  • 일정 Age(기본 15) 이상 살아남은 객체가 Promotion 됩니다.
  • 메모리가 부족하면 Major GC 가 실행되어 긴 지연이 발생할 수 있습니다.

3. Metaspace (旧 PermGen)

  • 클래스 로딩 시 메타데이터·정적 변수 등을 저장합니다.
  • XX:MaxMetaspaceSize 로 크기를 제한할 수 있습니다.

힙 메모리 동작 흐름

  1. 객체 생성 → Eden에 배치
  2. Minor GC → 사용되지 않는 Eden 객체 제거, 생존 객체는 S0/S1 이동
  3. 객체 승격 → Survivor Age를 채운 객체가 Old Gen으로 이동
  4. Major / Full GC → Old Gen 청소 + 필요 시 전체 힙 압축
public class HeapDemo {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        while (true) {          // 메모리 폭증
            list.add(new byte[1_000_000]); // 1 MB 객체
        }
    }
}

위 코드를 java -Xmx128m HeapDemo 로 실행하면 OutOfMemoryError: Java heap space 가 재현됩니다.


JVM 힙 크기 설정 팁

  • Xms512m – 힙 초기 크기
  • Xmx2g – 힙 최대 크기
  • XX:+UseG1GC – 저지연 G1 GC 사용
  • XX:MaxGCPauseMillis=200 – 목표 GC Pause 시간 힌트

힙 메모리 최적화 전략

  • 짧은 객체 생명주기 유지 – 필요 이상으로 참조를 남겨두지 않기
  • 배치 할당 (객체 풀) – 반복 생성 비용·GC 부담 완화
  • GC 로그 분석 (Xlog:gc*) – Minor/Major 비율·Pause 패턴 확인 후 튜닝
  • Metaspace 한도 설정 – 클래스 동적 생성이 많은 시스템의 메모리 폭주 방지

정리 질문

  1. Young Gen 크기를 늘리면 성능이 좋아질까요?

    객체 생성·소멸이 많은 애플리케이션은 Minor GC 횟수가 줄어 성능 개선 효과가 있습니다.

  2. Metaspace도 가비지 컬렉션 대상인가요?

    네, 클래스 언로딩 단계에서 회수되지만 빈도가 낮습니다.

  3. G1 GC는 언제 선택하나요?

    힙이 4 GB 이상이거나 지연 시간(Pause) 요구가 까다로운 서버 애플리케이션에 적합합니다.

  4. System.gc() 호출은 안전한가요?

    강제 Full GC 로 응답 지연을 유발할 수 있으므로, 프로파일링 후 필요한 경우에만 사용하세요.

  5. 메모리 누수를 GC가 자동 해결하나요?

    객체가 여전히 참조되고 있으면 GC가 회수할 수 없습니다. 코드에서 참조를 해제해야 합니다.

카테고리:

업데이트:

댓글남기기