본문 바로가기

TIL

Garbage Collection(GC) 이란?

Garbage collection 이란??

저번에 학습했던 Java JVM의 메모리 영역에 대해서학습 했었습니다.
그중 Java Visualizer 사이트에서 실제 메모리에 어떻게 데이터가 쌓이는지 확인 하는 중, 그럼 스택 에어리어에서 변수들 (ex. int age) 같은 데이터들은 한번 적재 되고 나서는 계속 메모리에 등록이 되어있는건가? 저런 변수가 1,000개 10,000개가 되면 어떤 문제가 발생하지 않을까? 하는 생각이 들었습니다.

이런 더이상 쓸데없는 데이터들을 처리해 주는 것이 Garbage coolection
동적으로 할당 했던 메모리 중 필요 없게 된 메모리 객체(garbage)를 모아 주기적으로 제거 하는 프로세스입니다.

for (int i = 0; i < 10000; i++) {
  Ramen ramen = new Ramen();  
  ramen.맛있어지기();
}

이런 코드가 있다고 생각해보자.
그럼 10,000번의 라면의 객체를 생성하고 맛있어지기 라는 함수를 실행을 할 것입니다.

이후 다른 Icecream 라는 객체를 불러와 달달해지기를 똑같이 10,000번 실행하면

for (int i = 0; i < 10000; i++) {
  Icecream icecream = new Icecream();  
  icecream.달달해지기();
}

이 코드를 실행할 시점에 이미 메모리에 10,000 개의 라면이 올라가있어서 아이스크림이 들어갈 공간이 부족 해질것입니다. 하지만 java에서는 한번 사용하고 버려지는 객체들을 주기적으로 비워줌으로써 한정된 메모리를 효율적으로 사용할 수 있게 해줄거라 생각합니다.

Garbage collection의 단점

가비지 컬랙션은 메모리가 언제 해제되는지 정확하게 알 수 없어 제어하기 힘들며, 가바자 컬랙션이 동작하는 동안에는 다른 동작이 멈추기 떄문에 오버헤드가 발생 되는 문제점이 있다.

이를 전문적인용어로 Stop-The-World 라고 한다고 합니다.

따라서 어플리케이션의 사용성을 유지하면서 효율적으로 GC를 실행하는 최적화 작업이 개발자의 숙제가 된다.

가비지 컬렉션 대상

가비지 컬렉션은 어떤 객체를 garbage로 판단해서 스스로 지워버릴까?
도달성, 도달능력(Reachability)라는 개념을 적용한다.

객체에 레퍼런스가 있다면 Reachable로 구분되고, 객체에 유효한 레퍼런스가 없다면 Unreachable로 구분 해버리고 수거해버린다.

  1. Reachable : 객체가 참조 되고있는 상태.
  2. Unreachable : 객체가 참조 되고있지 않은 상태(GC의 대상이 됨)
    여기서 참조는 힙영역의 데이터는 stack 이나 method area에서 실제 데이터를 참조한다고 이해하고 있습니다.(주소값을 가지고있다)

    함수가 끝나거나 특정 이벤트 등으로 인하여 참조 주소를 가진 변수가 삭제되는 현상이 발생하면, 위의 그림에서의 빨간색 객체와 같은 참조하고 있지 않은 객체들이 발생을 하게된다.

이러한 객체들을 가바지 컬랙션이 청소를 하게되는 대상이 된다.


가비지 컬렉션 청소 방식

Mark And Sweep
mark-sweep 이란, GC이 동작하는 아주 기초적인 청소 과정입니다.
가지비 컬렉션이 될 대상 객체를 식별(mark), 제거(sweep)하고 제거되어 파편화된 메모리 영역을 앞에서부터 채워나가는 작업을 수행합니다.

  1. 먼저 그래프 순회를 통해 연결된 객체들을 찾아내어 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다.
  2. 참조하고 있지 않은 객체를 제거
  3. compact 과정 분산된 객체들을 heap의 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 압축한다.

청소 단계별 모습

외 예시로 군대나 학교에서 강당같은곳에서 어떤 활동을 할때 앞에서부터 채워 앉으라고 하지않은가?
3번은 제거되어 비어있는 자리를 다시 채우기위해 이런 과정을 한다고 이해하면 될거같습니다.


동작 과정

haep 메모리의 구조

JVM의 힙(heap) 영역은 동적으로 레퍼런스 데이터가 저장되는 공간으로서, 가비지 컬렉션에 대상이 되는 공간이다.

아니 그럼 이쯤 내가 가진 의문에서 다시 시작을 해보면 stack area에서 수만개의 변수가 선언 되어있으면 문제가 되는거 아니냐?
==> 맞다

만약 int age;같은 변수가 수십 수백개가 선언되어있다면 바로 메모리가 부족에서 에러가 발생할것입니다.
그러나 이를 해결 하기위해 우리가 클래스를 만들고 함수를 만들어서 사용하는 것입니다.

함수를 만들어 그안에 변수를 선언 하면 함수가 종료될 시점에 해당 참조변수는 stack에서 빠져나가 사라지기 때문에 우리가 이렇게 객체를 지향해서 코드를 만드는 이유가 여기서 나오는것이라고 생각합니다.
또한 이렇게 참조 변수를 지워도 heap영역에 데이터는 그대로 남아있기 때문에 GC가 필요한것이라고 생각합니다.

이어서 heap영역에 대해 조금 더 설명을 하자면 두가지의 전제를 가지고 설계가 되었다고합니다.

  1. 대부분의 객체는 금방 접근 불가능한 상태가된다.
  2. 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.

객체는 대부분 일회성이며, 메모리에 오랫동안 남아있는 경우는 드물다 라고 합니다.

이러한 특성을 이용해 JVM개발자들은 효율적인 메모리 관리를 위해, 객체의 생존 기간에 따라 물리적인 Heap영역을 나누게 되었고
Young 과 Old 영역 총 2가지 영역으로 설계하였다.

heap의 구조

이름에서도 알 수 있듯
Young 영역 : 새롭게 생성된 객체가 할당 되는 영역 여기서 일어나는 가비지 컬렉션을 minor GC라고 부른다
Old 영역 : Young 영역에서 접근가능(Reachable) 상태를 유지하여 살아남은 객체가 복사되는 영역 young영역보다 크게 할당되며 GC는 적게 발생을 한다, 여기서 발생하는 GC를 Major GC 또는 full GC라고 부른다.

또다시 young 영역은 더 효율적으로 GC를하기 위해 3가지(Eden, Survival0 ,Survibal1)로 나뉜다.

Young영역 의 구조

  • Eden
     - new 를 통해 새로 생성된 객체가 위치
     - 정기적인 쓰레기 수집 후 살아남은 객체들은 Survivor영역으로 보냄
  • Survivor 0/1
     - 최소 1번의 GC에서 살아남은 객체가 존재하는 영역
     - Survivor 0 ,Survivor 1둘 중 하나는 꼭 비어있어야 한다.

Minor GC

해당 부분은 그림으로 보는게 훨씬 이해가 잘 되었습니다.

  1. 처음 생성된 객체는 Eden 영역에 위치
    처음 생성된 객체

  1. 객체가 계속 생성되어 Eden영역에 꽉 차면 Minor GC가 실행
  2. Mark를 위해 reachable 객체를 탐색
  3. Eden 영역에서 살아남은 객체를 Survivor영역으로 이동
  4. Eden 영역에서 사용되지 않은 객체의 메모리를 해제 (sweep)
  5. 살아남은 객체들은 age가 1씩증가
  6. 또다시 Eden 영역이 가득 차면 다시한면 Minor GC 발생.
  7. mark한 객체들을 비어있는 survival로 이동하고 다시 살아남은 객체들은 age가 1씩 증가.

이러한 과정을 반복하게 됩니다.

과정 반복

Major GC (Full GC)

  1. 객체의 age가 임계값(여기선 8)에 도달하면
  2. 이 객체들은 Old 영역으로 이동하며 이를 promotion이라 부른다.
  3. 위의 과정이 반복되어 Old영역의 공간이 부족해지면 Major GC가 발생되게 된다.

Major GC는 Old영역이 가득차면 실행하는 단순한 방식입니다.
하지만 young 영역에 비해 큰 공간을 가지고있어서 객체 제거에 더 많은 시간이 걸리게 되며, 10배 이상의 시간을 사용하게 됩니다.

여기서 초반에 말했던 Stop-the-world가 발생하게 됩니다.

MajorGC가 일어나면 Thread가 멈추고 CPU에 부하를 주기 떄문에 멈추거나 버벅이는 형상이 일어납니다.

그래서 자바 개발진들은 끊임 없이 가비지 컬렉션 알고리즘을 발전 시켜웠다고 합니다.

(알고리즘에 대해 작성해볼까 했지만 솔직히 읽어봐도 어떤식으로 동작하는지 하나도 모르겠고 종류도 너무 많아서 포기했습니다...나중에 다시한번 도전 해보도록 하겠습니다..)

 

다시 한번 글을 새벽에 읽어봤는데 오타도 많고 글이 조금 읽기 힘들게 작성된 부분이있는거같습니다..
다른날 다시 정리해서 한번 더 작성해 보도록 하겠습니다

 

참고 링크

 

☕ 가비지 컬렉션 동작 원리 & GC 종류 💯 총정리

Garbage Collection(GC) 이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객

inpa.tistory.com

 

'TIL' 카테고리의 다른 글

Flowchart에 대하여.  (0) 2026.01.13
싱글톤 패턴(Singleton Pattern)이란?  (1) 2026.01.13
객체지향 이해하기 -1 (배경 지식)  (0) 2026.01.09
Hello Java!  (1) 2026.01.08
git revert ,rebase, amend, Squash  (0) 2026.01.07