[면접스터디] 자바 5주차 - JVM과 GC 심화 (1~8)

동춘·2024년 11월 26일

[면접스터디] 자바

목록 보기
14/15

1. GC에서 사용하는 알고리즘은 무엇이 있고, Java에서는 어떤 알고리즘을 사용하나요?

메모리를 효율적으로 관리하기 위해 Mark-and-Sweep, Copying, Mark-Compact, Generational GC 등의 알고리즘을 사용합니다.
Java에서는 객체의 생존 특성을 활용해 Young Generation에 Copying을 그리고 Old Generation에 Mark-and-Sweep 또는 Mark-Compact 방식을 적용합니다.
Java 8은 기본적으로 Parallel GC, Java 11부터는 G1 GC를 디폴트로 사용합니다.

1. GC에서 사용하는 주요 알고리즘

  1. Mark-and-Sweep:
  • 동작 원리:
    • GC Root에서 시작하여 사용 중인 객체를 식별(Mark 단계)하고, 사용되지 않는 객체를 제거(Sweep 단계)합니다.
  • 장점: 단순하고 안정적.
  • 단점: 메모리 단편화가 발생할 수 있음.

2.Copying:

  • 동작 원리:
    • 메모리를 두 영역으로 나누고, 사용 중인 객체를 한 영역에서 다른 영역으로 복사합니다.
      복사가 완료된 후, 이전 영역은 초기화됩니다.
  • 장점: 메모리 단편화 없음.
  • 단점: 사용 가능한 메모리의 절반만 사용 가능.

3.Mark-Compact:

  • 동작 원리:
    • Mark 단계에서 사용 중인 객체를 식별하고, Compact 단계에서 사용 중인 객체를 한쪽으로 이동하여 메모리 단편화를 해결합니다.
  • 장점: 단편화를 해결.
  • 단점: Compact 단계에서 비용 발생.

4.Generational Garbage Collection:

  • 동작 원리:
    • 객체를 생성 시기와 생존 기간에 따라 Young Generation과 Old Generation으로 나눔.
    • Young Generation은 Copying 알고리즘을 사용하여, 새로 생성된 객체를 빠르게 정리합니다.
    • Old Generation은 Mark-and-Sweep 또는 Mark-Compact 알고리즘을 사용하여, 오랜 기간 생존한 객체를 정리합니다.
  • 장점: 객체의 생존 패턴을 활용해 효율적으로 관리.

2. Java에서 사용하는 GC 알고리즘

  1. Serial GC
  • 특징:
    • 단일 스레드로 GC를 수행.
      • Young Generation은 Copying 알고리즘, Old Generation은 Mark-Compact 알고리즘 사용.
  • 장점:
    • 메모리 관리가 간단하고, 작은 힙 메모리에서 효율적.
  • 단점:
    • 단일 스레드로 실행되므로, 멀티코어 환경에서는 비효율적.
  • 적합한 환경:
    • 단일 스레드 애플리케이션이나 작은 메모리 환경.
  1. Parallel GC (기본 GC in Java 8)
  • 특징:
    • Young Generation과 Old Generation 모두에서 병렬 GC를 수행.
    • 다수의 스레드를 활용하여 GC를 병렬로 처리.
  • 장점:
    • 멀티코어 환경에서 효율적이며, 처리 속도가 빠름.
  • 단점:
    • 정지 시간(STW)이 길어질 수 있음.
  • 적합한 환경:
    • 고성능 서버나 멀티코어 시스템.
  1. CMS GC (Concurrent Mark-Sweep)
  • 특징:
    • Old Generation을 대상으로 병렬로 수행되며, 정지 시간을 줄이기 위해 설계.
    • 대부분의 작업을 애플리케이션과 병렬로 수행.
  • 장점:
    • Stop-the-World(STW) 시간을 최소화.
  • 단점:
    • 메모리 단편화가 발생할 수 있음.
    • CPU 자원을 많이 소비.
  • 적합한 환경:
    • 응답 시간이 중요한 시스템(예: 웹 애플리케이션).
  1. G1 GC (Garbage-First Garbage Collector)
  • 특징:
    • 힙을 고정 크기의 Region으로 나누고, 가비지가 많은 Region을 우선적으로 정리.
    • Young Generation과 Old Generation을 논리적으로 관리.
  • 장점:
    • 짧은 정지 시간(STW)을 유지하며, 큰 힙 메모리에서 효율적.
  • 단점:
    • CMS GC보다 CPU 오버헤드가 크지만, 최신 JVM에서 최적화됨.
  • 적합한 환경:
    • 대규모 메모리를 사용하는 시스템.
  1. ZGC (Z Garbage Collector)
  • 특징:
    • Java 11에 도입된 최신 GC로, 초저지연(정지 시간 몇 밀리초 이내)을 목표로 설계.
    • 힙 메모리 크기(수 TB 이상)에서도 안정적으로 동작.
  • 장점:
    • 정지 시간이 거의 없음.
  • 단점:
    • CPU와 메모리 자원을 많이 소비.
  • 적합한 환경:
    • 대규모 메모리와 초저지연이 요구되는 시스템.

2. Java 8 기준으로, GC는 어떤 방식으로 수행되나요?

Java 8의 기본 GC는 Parallel GC로, Young Generation에서는 Copying 알고리즘을 사용해 살아남은 객체를 Survivor 영역으로 이동하고 나머지는 정리합니다.
Old Generation에서는 Mark-and-Sweep 또는 Mark-Compact 알고리즘을 사용해 오래 살아남은 객체를 정리합니다.
Full GC는 힙 전체를 대상으로 수행되며, 메모리가 부족하거나 GC가 비효율적으로 동작할 때 발생합니다.

  1. Young Generation GC (Minor GC)는 새로 생성된 객체를 빠르게 정리하는 단계입니다.
  • Young Generation에서 Copying 알고리즘을 사용하여, 살아남은 객체를 Survivor 영역으로 이동시키고, 사용되지 않는 객체는 정리합니다.
  • 이 단계는 자주 발생하지만, 상대적으로 빠르게 수행되므로 애플리케이션에 미치는 영향이 적습니다.
  1. Old Generation GC (Major GC)는 Old Generation 영역에 있는 객체를 정리하는 단계입니다.
  • 이 과정에서는 보통 Mark-and-Sweep 또는 Mark-Compact 알고리즘이 사용됩니다.
  • Old Generation은 Young Generation보다 정리가 덜 자주 일어나지만, 한 번 발생할 때는 Stop-the-World(STW) 이벤트가 발생해 애플리케이션이 일시적으로 중단됩니다.
  • Major GC는 발생할 때 성능에 큰 영향을 미칠 수 있기 때문에, Old Generation으로의 객체 이동과 GC 수행 빈도를 관리하는 것이 중요합니다.
  1. Full GC는 힙 전체(Young Generation + Old Generation)를 대상으로 수행됩니다.
  • 일반적으로 메모리가 부족하거나 가비지 컬렉션이 효율적으로 이루어지지 않을 때 발생합니다.
  • Full GC는 수행 시간이 오래 걸리고, 애플리케이션의 성능에 상당한 영향을 미칠 수 있기 때문에, 발생 빈도를 최소화하는 것이 중요합니다.

3. 왜 Heap 영역은 Young Generation과 Old Generation으로 나뉘나요?

객체의 생존 특성을 기반으로 메모리 관리를 효율적으로 수행하기 위함입니다. Heap 영역은 객체의 생존 특성에 따라 Young Generation과 Old Generation으로 나뉩니다.
짧은 생존 기간을 가진 객체는 Young Generation에서 빠르게 정리하고, 오래 살아남은 객체는 Old Generation으로 이동해 관리 효율성을 높입니다.
이러한 구조는 GC의 빈도를 줄이고 성능 최적화를 가능하게 합니다.

  1. 객체 생존 특성:
  • 대부분의 객체는 짧은 생존 기간을 가집니다. 예를 들어, 임시 객체나 메서드 호출 중 생성된 객체는 메모리에서 빠르게 소멸됩니다.
  • 반면, 일부 객체는 애플리케이션의 상태를 저장하거나 장기간 유지되어야 하는 긴 생존 기간을 가집니다.
  1. 효율성:
  • 짧은 생존 기간을 가진 객체는 Young Generation에서 Copying 알고리즘을 사용하여 빠르게 정리됩니다. 이렇게 하면 힙 전체에서 GC를 수행하는 것보다 훨씬 효율적입니다.
  • 오래 살아남은 객체는 Young Generation을 거쳐 Old Generation으로 이동하며, Old Generation에서 자주 정리되지 않습니다. 이렇게 하면 GC의 빈도를 줄이고, 힙 메모리 관리를 체계적으로 수행할 수 있습니다.
  1. 성능 최적화:
  • Young Generation에서는 Minor GC를 자주 수행하여, 짧은 시간 내에 불필요한 객체를 제거하고 메모리를 회수합니다.
  • Old Generation에서는 Major GC를 드물게 수행하여, 애플리케이션의 성능에 미치는 영향을 최소화합니다.
  • 이러한 구조는 GC의 빈도와 정지 시간을 줄이는 데 크게 기여합니다.

정리하자면, Heap 메모리를 Young Generation과 Old Generation으로 나누는 것은 객체의 생존 특성을 활용하여 GC를 효율적이고 빠르게 수행하기 위한 설계입니다. Young Generation에서 자주 발생하는 GC는 짧은 생존 기간의 객체를 정리하고, Old Generation에서는 장기간 생존하는 객체를 관리하여, 메모리 사용과 GC 성능을 최적화합니다.

4. GC의 실행 방식을 아는 만큼 설명해 주세요.

GC는 Mark 단계에서 GC Root에서 출발해 모든 객체를 탐색,순회하여 참조 가능한 객체를 식별하고, 참조되지 않는 객체를 가비지로 간주합니다.
Young Generation은 Copying 알고리즘으로 살아남은 객체를 Survivor 영역으로 이동하며, Old Generation은 Mark-and-Sweep 또는 Mark-Compact 방식으로 정리합니다.
GC 실행 중에는 Stop-the-World 이벤트가 발생해 애플리케이션이 일시적으로 중단될 수 있습니다.

  1. 객체 참조 여부 확인 (Mark 단계):
  • GC Root에서 시작하여 참조 가능한 객체를 식별.
  • 참조되지 않는 객체는 "Garbage"로 간주.
  1. 메모리 정리:
  • Young Generation에서는 Copying 알고리즘을 사용하여 객체를 Survivor 영역으로 이동.
  • Old Generation에서는 Mark-and-Sweep 또는 Mark-Compact 방식 사용.
  1. 메모리 단편화 해결:
  • Mark-Compact 알고리즘을 사용하여 메모리 단편화를 방지.
  1. Stop-the-World 이벤트:
  • GC가 실행되는 동안 JVM은 애플리케이션 실행을 일시 중단.

5. (다듬어보기) Java 8과 Java 11의 디폴트 GC 실행 방식은 어떤 것인가요?

Java 8의 디폴트 GC는 Parallel GC로, Young Generation에서 Copying 알고리즘을, Old Generation에서 Mark-and-Sweep 또는 Mark-Compact 알고리즘을 사용합니다.
Java 11의 디폴트 GC는 G1 GC로, 힙을 Region 단위로 나누어 가비지가 많은 영역을 우선적으로 정리하며, 짧은 정지 시간을 유지합니다. (우선순위 기반 처리)
Java 11에서 G1 GC는 큰 힙 메모리에서도 성능과 정지 시간을 효율적으로 관리하기 위해 기본값으로 채택되었습니다.

  1. Java 8:
  • 기본 GC는 Parallel GC.
  • 다수의 스레드를 활용해 GC를 병렬로 수행.
  1. Java 11:
  • 기본 GC는 G1 GC.
  • 성능 개선과 정지 시간(STW) 최소화를 목표로 설계.

6. (다듬어보기) G1 GC에 대해 설명해 주세요. region 얘기 말고도 pause시간, 목표등을 같이 말하기

G1 GC(Garbage-First Garbage Collector)는 힙을 고정 크기의 Region으로 나누어 관리하며, 가비지가 많은 Region을 우선적으로 정리합니다. (우선순위 기반)
Young Generation과 Old Generation을 논리적으로 분리하고, 짧은 정지 시간(STW)을 유지하도록 설계되었습니다.
특히, 큰 힙 메모리 환경에서 효율적으로 동작하며, Java 11부터 기본 GC로 사용됩니다.

특징

  1. Region 기반 메모리 관리:
  • 힙을 고정 크기의 Region으로 분할. ( 우선순위를 할당하기위해 작은 단위로 나눈다 )
  • Young Generation, Old Generation을 논리적으로 관리.
  1. Pause Prediction Model:
  • GC가 정지 시간을 예측하고, 목표 정지 시간을 유지.
  1. Concurrent Marking:
  • GC가 애플리케이션과 병렬로 실행되어 정지 시간을 최소화.
  1. 가비지 우선 정리:
  • 가비지가 많은 Region을 우선적으로 정리하여 효율성 향상.

7. G1 GC의 Heap 구조를 설명해 주세요.

G1 GC는 힙을 고정 크기의 Region으로 나누어, 각각 Young Generation, Old Generation, Humongous Region 등의 역할을 수행합니다.
Young Generation은 Eden과 Survivor 영역으로 구성되며, 짧은 생존 객체를 빠르게 정리합니다.
Old Generation은 오래 생존한 객체를 저장하고, Humongous Region은 큰 객체를 효율적으로 관리합니다.

  1. Young Generation:
  • 새로 생성된 객체가 저장.
  • Eden Region과 Survivor Region으로 구성.
  1. Old Generation:
  • Young Generation에서 오래 살아남은 객체가 이동.
  1. Humongous Object Region:
  • 매우 큰 객체(Region 크기의 50% 이상)가 저장.

작동 방식

  1. Young Generation에서 Minor GC 발생.
  2. Marking 단계를 통해 가비지가 많은 Region을 식별.
  3. 가비지가 많은 Region을 우선적으로 정리.

8. 왜 Java 11은 디폴트 GC를 G1 GC로 변경하였을까요?

Java 11은 정지 시간을 줄이고 큰 힙 메모리에서의 효율성을 위해 G1 GC를 디폴트로 채택했습니다.
G1 GC는 힙을 Region으로 나누어 가비지가 많은 영역을 우선 정리하고, 짧은 정지 시간을 유지하도록 설계되었습니다.
이러한 특성은 대규모 애플리케이션에서 성능 최적화와 안정성을 제공하기 때문입니다.

  1. 정지 시간(STW) 최소화:
  • G1 GC는 정지 시간을 예측하고, 짧은 정지 시간을 유지하도록 설계.
  • 대규모 애플리케이션에서 사용하기 적합.
  1. 큰 힙 메모리에서 효율적:
  • Region 기반 메모리 관리를 통해 큰 힙에서도 성능을 유지.
  1. GC 성능 향상:
  • Java 11에서 G1 GC의 병렬 처리 및 메모리 정리가 더욱 최적화됨.
  1. 운영 효율성:
  • 사용자가 별도의 설정 없이도 G1 GC의 이점을 누릴 수 있음.
profile
건강하개

0개의 댓글