티스토리 뷰

이번 글은 3번 JVM 가비지 컬렉션에 대해서 작성한다.

1. JVM 구성 요소와 JVM Warm-up 전략
2. JVM 메모리 구조
3. JVM 가비지 컬렉션
4. 자바 어플리케이션 실행 과정
5. Java 비동기 처리 (프로세스, 쓰레드, 비동기 처리)

 

 

Java는 Garbage Collection(GC)을 사용해서 개발자가 메모리 할당과 해제를 수동으로 처리하지 않아도 된다.

가비지 컬렉션을 통해 JVM이 사용하지 않는 객체를 자동으로 찾아서 메모리를 해제해주기 때문이다.

메모리 관리는 성능에 직접적인 영향을 끼치기 때문에 올바른 메모리 관리와 GC에 대한 이해가 필요하다.

 

1. 가비지 컬렉션

 

Java 메모리의 각 영역에서 더 이상 사용되지 않는 객체가 존재하면,

JVM이 사용하지 않는(참조가 존재하지 않는) 객체들은 메모리에서 제거된다.

 

1.1. 가비지 컬렉션의 특징

  • 자동화된 메모리 관리: 개발자는 명시적으로 메모리를 해제하지 않아도 된다.
  • 힙 메모리 관리: 힙 영역에서 사용되지 않는 객체를 탐지하여 회수한다.
  • 객체의 생존 시간에 따른 관리: 오래 살아남은 객체는 더 적게 검사한다.

1.2. GC가 필요하지 않은 경우

로컬 변수메서드의 매개변수Stack 메모리에 저장되며, 메서드가 종료되면 자동으로 메모리에서 제거되므로 GC의 대상이 아니다.

 

 

 

 

2. Young/Old 영역과 GC의 동작 방식

JVM Heap 메모리는 크게 Young 영역Old 영역으로 나뉘며, 각각의 역할과 GC 동작 방식이 다르다.

 

 

2.1. Heap 메모리 구조

  1. Young Generation
    • Eden 영역
      • 새로 생성된 객체는 먼저 Eden 영역에 저장된다.
      • Eden 영역이 가득 차면 Minor GC가 발생하고, 참조되지 않는 객체는 제거된다.
    • Survivor 영역
      • Minor GC에서 살아남은 객체는 Survivor 영역으로 이동한다.
      • Survivor 영역은 두 개의 영역이 있음: Survivor1(S0), Survivor2(S1).
      • 객체는 Minor GC가 발생할 때마다 Survivor1과 Survivor2 사이를 이동하며, 이동 과정에서 참조되지 않는 객체는 제거된다.
    • Old Generation으로 이동
      • Minor GC를 여러 번 거친 오랫동안 살아남은 객체는 Old Generation으로 이동한다.
      • 이 과정에서 객체의 생존 기간을 관리하기 위해 age bit가 사용된다.
  2. Old Generation
    • Young 영역에서 Minor GC에서 살아남은 오래된 객체를 저장한다.
    • Long-lived 객체를 저장하며, Major GC 또는 Full GC로 관리한다.

 

 

2.2. GC의 동작 방식 (JVM 메모리에서 객체 이동 과정)

  1. 객체 생성 (Eden)
  2. 모든 객체는 Young Generation의 Eden 영역에 먼저 생성된다.
  3. Minor GC 발생 (EdenSurvivor)
    • Eden 영역에서 GC가 발생하며 참조되지 않는 객체는 제거된다.
    • 살아남은 객체는 Survivor 영역(S0 또는 S1)으로 이동한다.
  4. Survivor 영역을 오가며 생존
    • 객체는 Minor GC가 발생할 때마다 S0 ↔ S1 사이를 이동한다.
    • age bit 값이 증가하며, 특정 조건을 만족하면 Old Generation으로 이동한다.
  5. Old Generation 이동
    • Young Generation에서 오랫동안 생존하거나, Survivor 영역이 부족하면 Old Generation으로 이동한다.
  6. Full GC 발생
    • Old Generation을 포함한 전체 힙 메모리를 정리하기 위해 Full GC가 발생한다.
    • 실행 시간이 길고 성능에 영향을 줄 수 있다.
    • 따라서 Full GC를 최소화하도록 GC 알고리즘을 선택하고 튜닝해야한다.

 

 

3. 다양한 GC 알고리즘

3.1. Serial GC

  • 단일 스레드 환경을 위한 GC
  • GC 중 애플리케이션을 멈추는 Stop-the-World 시간이 길어진다.
  • 적합한 경우: 단일 스레드 환경, CPU 리소스가 제한된 애플리케이션
-XX:+UseSerialGC

3.2. Parallel GC

  • 여러 스레드 사용
  • Stop-the-World 시간이 줄어들어 멀티코어 CPU에서 효율적이다.
  • 적합한 경우: 높은 처리량(Throughput)이 필요한 애플리케이션
-XX:+UseParallelGC

3.3. CMS (Concurrent Mark-Sweep) GC

  • Old 영역에서의 GC 시간을 줄이기 위해 병렬 작업동시 작업을 수행한다.
  • 단점: 메모리 단편화 문제가 발생할 수 있다.
  • 적합한 경우: 짧은 응답 시간이 중요한 애플리케이션
-XX:+UseConcMarkSweepGC

3.4. G1GC (Garbage First GC)

  • YoungOld 영역을 여러 Region으로 나누고, GC가 필요한 지역부터 우선적으로 정리한다.
  • Stop-the-World 시간을 최소화하며, 큰 힙 메모리에서도 효율적이다.
  • 적합한 경우: 짧은 지연 시간(Low Latency)을 요구하는 대규모 애플리케이션
-XX:+UseG1GC

 

 

 

4. GC 모니터링과 튜닝

GC를 효율적으로 관리하기 위해 모니터링과 튜닝을 할 수 있다.

4.1. GC 로그 활성화

GC 로그는 GC 동작을 분석하고 성능 문제를 해결하는 데 도움을 줍니다.

java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log MyApplication

// 출력 예시
2024-11-19T14:30:20.123: [GC (Allocation Failure) [PSYoungGen: 1024K->256K(2048K)] 2048K->512K(4096K), 0.0123456 secs]
  • PSYoungGen: Young 영역의 GC 결과.
  • Allocation Failure: Eden 공간 부족으로 GC 발생.

4.2. 모니터링 툴

  1. JVisualVM: JVM 동작과 GC 활동을 실시간으로 시각화
  2. JConsole: 메모리 사용량, GC 횟수 등을 확인
  3. 애플리케이션 프로파일러: YourKit, Eclipse MAT

4.3. GC 튜닝 전략

1. 적절한 힙 크기 설정

-Xms512m -Xmx2048m

최소 힙 크기(Xms)와 최대 힙 크기(Xmx)를 설정할 수 있다.

 

2. GC 알고리즘 선택

애플리케이션 특성에 따라 Serial, Parallel, CMS, G1GC를 선택한다.

 

3. GC 목표 설정

-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=45

최대 GC 지연 시간(MaxGCPauseMillis)과 GC 트리거 임계값 설정

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함