[자바] Java GC (Garbage Collection)

보라보라·2024년 2월 20일
0

GC

목록 보기
1/3
post-thumbnail

Garbage Collection

GC(가비지컬렉션)는 뭐하는 애야?

  • 자바의 메모리 관리 방법 중 하나
  • JVM의 Heap영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객체(garbage := Unreachable)를 모아 주기적으로 알아서 제거하는 프로세스
  • 자바에만 있는 개념은 아님 (파이썬, 자바스크립트, Go, 웹브라우저 등)

[장점]

  1. 메모리 관리, 메모리 누수를 개발자가 관리하지 않아도 되어 개발에만 집중할 수 있음
  2. 한정된 메모리를 효율적으로 사용할 수 있음.

[단점]

  1. 메모리가 언제 해제되는지 정확하게 알수 없어 제어하기 힘듦
  2. 가비지 컬렉션(GC)이 동작하는 동안에 다른 동작을 멈추기 때문에 오버헤드가 발생되는 문제점 발생 (Stop-The-World)

STW(Stop-The-World)

GC를 수행하기 위해 JVM이 프로그램 실행을 멈추는 현상을 의미
GC가 작동하는 동안 GC관련 Thread를 제외한 모든 Thread는 멈추게 되어 서비스 이용에 차질이 생길 수 있다.
이 시간을 최소화 시키는 것이 쟁점!!!

가비지 컬렉션 대상

Reachable VS Unreachable

  • Reachable : 객체가 참조되고 있는 상태
  • Unreachable : 객체가 참조되고 있지 않은 상태(GC의 대상이 됨)

GC Roots

메모리 풀 외부에서 내부를 가리키는 포인터
메모리 정리를 위해 출발하는 지점

  • Java 스택, Java 메소드 실행 시에 사용되는 지역 변수와 파라미터들에 대한 참조
  • JNI에 의해 생성된 객체에 대한 참조
  • 메소드 영역의 정적 변수에 의한 참조 :
    정적 변수는 프로그램 수명 동안 존재하며, 다른 객체들에 대한 참조를 유지할 수 있습니다.

GC Roots의 참조를 받는 메모리는 Reachable함.
더하여 힙영역 내의 다른 객체에 의한 참조도 Reachable하다고 판단 됨.

JNI : Java로 구현하기 힘든 기능에 대해 Native Code를 사용하는 기능(자바와 다른 언어를 연동하는 기능)

  • 하드웨어 제어가 필요한 경우
  • 프로세스의 성능 향상
  • 자바에서 지원되지 않는 특정 운영체제 서비스
  • 기존에 작성된 프로그램(라이브러리)과의 연계

예시

그림으로 보는 예시

  • 1, 5번 객체 : 스택 영역에서 참조하여 Reachable
  • 3번 객체 : 메소드 영역에서 참조되어 Reachable
  • 4번 객체 : 힙 영역에서 참조되어 Reachable
  • 2번 객체 : 어느 곳에서도 참조되고 있지 않아 Unreachable
    -> 나는야 GC의 대상!!!!

코드로 보는 예시

Person person = new Person();
person.setName("Bora");
person = null; // java에서 명시적으로 불필요한 데이터를 표현하기 위해서 일반적으로 null을 선언

// 가비지 발생
person = new Person();
person.setName("Boradol2");

나중에 Effective Java item7. 다 쓴 객체 참조를 해제하라 보기.

가비지 컬렉션 청소 방식

그렇다면 GC는 어떻게 해제할 동적 메모리 영역들을 알아서 판단하게 될까?

GC 알고리즘 - Reference Counting

  • 메모리의 각 객체에 대한 포인터 수를 유지 관리 합니다.
  • 각 포인터의 수는 개체에 대한 참조가 생성되거나 소멸될 때 필요에 - 따라 증가하거나 감소.
  • 개체의 참조 횟수가 0에 도달하면 해당 개체가 회수됨.
    -> 나는야 GC대상!!!
  • 아래 그림의 RootSpace는 실제로 가비지 컬렉션을 수행하는데 사용되는 메모리 영역.
  • 아래의 초록색 영역이 Reference Count
    https://rebelsky.cs.grinnell.edu/Courses/CS302/99S/Presentations/GC/
  • 한계 :
    • 순환참조 : 객체 그룹에 포인터 순환이 포함되어 있으면 참조 횟수가 0에 도달할 수 없으므로 회수되지 않음. 곧 Memory Leak(메모리 누수)가 발생.

GC 알고리즘 - Mark and Sweep, Compact

Reference Counting의 순환참조 문제를 해결할 수 있음.
Java에서는 이 방식으로 메모리 관리 함.

Mark

GC Roots로 부터 모든 변수를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾아서 마킹
마킹 단계에서 참조된 객체참조되지 않은 객체를 판별하기 위해 모든 객체를 검사해야하는 시간이 많이 걸리는 프로세스이다.

Sweep

Unreachable한 객체들을 Heap에서 제거하고 Reachable한 객체와 포인터를 여유공간에 남겨둔다.

Compact

알고리즘에 따라 이 과정이 추가되기도 함.
Sweep 후에 분산된 객체들을 Heap의 시작주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 나눈다.
성능을 더욱 향상시키기 위해 나머지 객체들을 압축하는 것을 의미한다.
새로운 메모리 할당이 훨씬 쉽고 빨라진다.
메모리 단편화를 막아준다.

메모리 단편화
주기억장치에서 메모리 공간이 작은 조각으로 나뉘어져 사용가능한 메모리가 충분히 존재하지만 할당이 불가능한 상태

단점

  • 의도적으로 GC를 실행시켜야 함.
  • 어플리케이션 실행과 GC실행이 병행된다 : 어느 순간에는 실행중인 어플리케이션이 GC에게 컴퓨터 리소스들을 내줘야 함.

따라서 어플리케이션의 사용성을 유지하면서 효율적이게 GC를 실행하는것이 꽤나 어려운 최적화 방법임.

Mark And Sweep의 특징으로 알아보는 결론

의도적으로 GC를 실행시켜야한다.

  • 이 때 한번 GC한번 실행 시켜봐야 겠다. 이 때가 언제인가?
  • 바로 다음 글 가비지 컬렉션의 동작 방식에서 알아볼 것이다.

어플리케이션 실행과 GC의 실행이 병행된다.

  • JVM은 어떤 방식으로 어플리케이션 실행과 GC의 실행을 병행할 수 있을까?
  • 바로 Stop-The-World를 최소화하는 방식이다
  • 이 다음다음 글 가비지 컬렉션 알고리즘의 종류에서 알 수 있다.

일단, 이번 글은 가비지 컬렉션과 가비지 컬렉션의 대상과 자바에서 GC가 어떻게 GC의 대상을 판단하는지의 방법까지 알아보았다.
다음 글에서는 가비지 컬렉션의 동작 과정에 대해 알아보겠다.


[참고]

profile
쉽게쓰려고 노력하는 블로그

0개의 댓글