Post

01 GC

01 GC

메모리 관리가 적절히 이루어지지 않을 경우, 메모리 누수 및 자원 고갈로 인해 프로그램이나 운영체제가 비정상적으로 종료될 위험이 존재함.

1. 메모리 관리

1. 메모리 관리를 하지 않으면

  • 메모리 누수(Memory Leak)는 프로그램 또는 운영체제의 비정상 종료를 초래할 수 있음.
  • 잘못된 메모리 접근(Dangling Pointer)은 메모리 손상 및 보안 취약점으로 이어질 위험이 있음.
  • 적절한 메모리 관리 부재 시 사용 가능한 메모리 자원이 점진적으로 감소하여 시스템 성능 저하를 유발함.

2. C의 메모리 관리

  • 언어 설계 철학은 “개발자가 모든 것을 통제한다”
  • 개발자가 메모리 할당(malloc)과 해제(free)를 직접 제어함.
  • 자동 GC는 운영체제가 아닌 코드가 자원 쓰는 방식에 개입하므로, C의 “개발자 직접 제어” 철학에 어긋남.

3. JAVA의 메모리 관리

  • 자바의 핵심 철학은 “개발자가 개발 로직에 집중하게 한다”
  • 메모리 해제를 신경 쓰지 않아도 되니 개발자가 비즈니스 로직 개발에만 집중 가능
  • 자바는 JVM이라는 가상 머신 위에서 실행되기 때문에 객체 생성/참조 추적/해제를 런타임에서 통합적으로 제어가능함.

2. Garbage Collection / Garbage Collecter

1. Garbage Collection

  • 더 이상 사용되지 않는 객체를 자동으로 메모리에서 제거하는 과정(Process)
  • Garbage Collection이 실행되면, 힙에서 사용하지 않는 객체들이 제거함.

2. Garbage Collecter

  • Garbage Collection을 실행하는 주체(기계, 프로그램, 알고리즘)
  • Garbage Collector가 동작하면, Young 영역의 Eden에서 객체를 Survivor로 복사함.
  • 별도로 메모리를 관리하지 않아도, 메모리 누수와 같은 문제를 방지할 수 있음.

3. Garbage Collection의 Reachability

1. Reachability(도달 가능성)

  • JVM 내부에서 어떤 객체가 “루트(root)” 객체를 통해 참조될 수 있는가?로 판단함.
루트 객체 종류설명
스레드의 지역 변수Java Stack 안의 변수들
메서드 매개변수현재 실행 중인 메서드에 전달된 값
static 변수클래스에 고정된 static 필드
JNI에서 참조 중인 객체네이티브 코드와 연결된 객체
  • 소스 상에서 참조값 기준
    1
    2
    
     MyClass obj = new MyClass();// 루트에서 "obj" 참조중, 루트에서 도달했다.
      obj = null;     //"obj"는 참조하는게 없음, 루트에서 도달 불가
    

2. GC가 Reachability를 확인하는 시점

  • JVM은 각 영역별로 ‘총 용량’과 ‘현재 사용량’을 내부적으로 관리하는데 “객체 할당 시마다”, “GC 주기마다” 메모리를 모니터링함.
  • GC가 움직이는 시점
모니터링중 작동시점GC 종류대상 영역
Eden이 가득 찼을 때Minor GCYoung 영역만
Old 영역 부족, System.gc() 등Full GC모든 영역 (Y + O + M)
백그라운드에서 주기적으로 탐색Concurrent GC주로 Old 영역

4. Garbage Collection의 heap area 활용

JVM GC 설계의 기본적인 Young Gen / Old Gen 구성방식으로 GC의 종류에 따라서 다르게 활용하기도 함.

1. Young영역 / Old 영역

  • Young에서 빠르게 객체를 빠르게 읽고 초기화하면서 객체들을 정리하는 역할을 수행하고, 정리하는 과정에서 객체들에게 age값을 먹여서 오래 쓰고 있는 객체들은 구분하고, 순차적으로 공간이 넓은 Old로 승격하여 관리함.

2. Young 영역(Young Generation)

  • Young 영역은 새롭게 생성된 객체
  • Eden 과 Survivor 0 / Survivor 1 구성됨
    • Eden은 객체를 참조할때 처음으로 저장되는 공간
    • Survivor 0/1은 1번 이상 GC작업으로 부터 살아남은 객체가 존재

3. Old 영역(Old Generation)

  • old영역은 Young영역에서 Reachable 상태를 유지하여 살아남은 객체

5. Garbage Collection 작업

JVM GC 설계에서 기본적인 Garbage Collection 방식으로 하드웨어의 성능이 좋아지고, 다양한 환경과 시스템이 등장하면서 작업 방식이 조금씩 변화함.

1. Young 영역

  • Young영역의 Eden에 객체가 저장됨.
    • 이곳은 입력만 진행하고, 꽉차면 Survivor로 필요한 것만 복사함.
    • 저장자체는 Survivor에서 하기때문에 Eden은 빠르게 쓰고 비우기만 함.
  • Eden 영역이 꽉차면 Young영역을 대상(Survivor+Eden)으로 Minor GC가 작업함

  • 살아남은 것은 다른 Survivor에 저장함.
    • Survivor을 두개로 분리하여 한쪽은 저장하는 공간, 한쪽은 기존에 있던 공간으로 번갈아가면서 사용함.
      • 1개의 Survivor을 사용하면, 데이터를 지우고, 최적화를 위해서 주소값들을 재정리하는데 시간이 소요됨. 따라서 새로운 공간에 새로운 순서로 Eden과 합쳐서 다시 저장하는 방식을 택함.
      • 데이터를 다옮기면 기존 Survivor공간은 비어있어서 처음부터 다시 작성함.
  • 데이터가 ‘승격’(promotion)함.
    • 살아남은 객체들은 age가 +1 상승함
    • age가 특정값이상이 되면 Old영역으로 넘어가는것을 ‘승격’이라 함.
    • age의 기준값은 JVM 옵션으로 설정 가능함.
    • survivor공간이 부족할경우 자동으로 old로 올라가는데, 이것을 동적승격(Dynamic Promotion)

2. Old 영역

  • Young영역의 객체 승격등으로 Old영역이 꽉차면 Major GC 실행
  • 참조되어 있는 값들만 mark 표기(사용중인 객체 확인)
  • 참조되어 있지 않은 객체는 Mark-Sweep 또는 Mark-Compact 방식으로 삭제
  • 단편화가 심할경우 Compact진행 (메모리 최적화)
This post is licensed under CC BY 4.0 by the author.