우당탕탕

[Java] 가비지 컬렉션(Garbage Collection)이란? (가비지 컬렉션 - 1) 본문

언어/Java

[Java] 가비지 컬렉션(Garbage Collection)이란? (가비지 컬렉션 - 1)

모찌모찝 2022. 8. 27. 07:00
가비지 컬렉션(GC)이란?

 

가비지 컬렉션(Garbage Collection , GC)

 가비지 컬렉션이란 개발자가 동적으로 할당한 메모리 영역 중 더 이상 사용하지 않는 자원을 해제하는 기능이다. Java의 경우 개발자가 직접 메모리를 해제하지 않아도 JVM의 가비지 컬렉터가 알아서 정리해준다.
(JVM 메모리 구조 중 Heap영역에서 사용하지 않는 객체를 삭제한다. 아래의 그림 참조 )

아래의 예시 코드로 한번 알아보자

Car car = new Car("K5");

car = new Car("K3");

 처음에 K5라는 차가 생성되고 car는 K5를 바라보고 있다 이때는 가비지가 존재하지 않는다. 하지만 이후 K3라는 차가 생성되고 car는 K3를 바라보게 된다.
K3를 바라보게 되는 순간부터는 K5라는 차는 더 이상 참조되지 않기 때문에 도달할 수 없는(Unreachable) 상태라고 하며 가비지 라 판단되고 메모리 공간이 회수당하게 된다.

아래는 JVM의 메모리 구조Heap영역이다.

출처 https://velog.io/@agugu95/%EC%9E%90%EB%B0%94%EC%99%80-JVM-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0

 

사진과 같이 Heap 영역에는 Eden , Suvivor1/2 , Old, Perm영역이 존재한다. ( Perm영역의 경우 Java8부터 제거됨 )

구조

1. Young Generation ( Young 영역 )
    a. Eden영역
    b. Survivor1 영역
    c. Survivor2 영역
2. Old Generation ( Old 영역 )

 

Young Generation (Young영역)

 Young 영역에는 Eden영역Survior영역이 두 개 존재한다. Young영역의 경우 새롭게 생성된 객체가 할당되는 영역이며, 대부분 객체는 금방 도달할 수 없는(Unreachable) 상태가 된다.

Young 영역에 대한 가비지 컬렉션은 Minor GC라고 부른다.

1. Eden영역

 Young영역 중에서도 제일 최근에 생성된 객체들이 위치한다.

2. Survivor영역

 영역은 두 개가 존재하는데 Eden영역이 꽉 차면 Survivor영역으로 온다. (영역이 두 개가 존재하는데 보기 쉽게 1,2로 나누는 것이지 우선순위가 존재하는 것은 아니다)

 Eden영역에서 Suvivor영역 1 또는 2로 옮겨지는 객체들은 어디선가 참조되고 있는 객체들이며, Suvivor영역 둘 중 하나의 영역이 꽉 차게 되면 공간이 남아있는 다른 Suvivor영역으로 이동하는 형식이다. 이러한 형식으로 Survivor영역 둘 중 하나는 항상 비워있는 공간이 유지된다.

 이러한 과정에서 Minor GC가 발생하며, Eden영역 또는 Survivor1/2 영역에서 사용되지 않는 객체의 메모리 할당을 제거한다.

 

Old Generation (Old 영역)

 Survivor 영역의 객체 중에 여러 번의 Minor GC과정에서 살아남은 객체들이 Old영역으로 넘어온다. Old 영역의 특징으로는 Young영역보다 크게 할당하며, GC의 경우에도 Young영역보다 빈도가 적게 발생한다.
( Survivor영역에서 넘어오는 경우 외에도 Eden영역에서 Old 영역으로 바로 넘어오는 경우가 존재하는데, 이는 객체의 크기가 Survivor영역의 크기보다 클 경우에만 발생된다. ) 

보통 Young영역에서 Minor GC가 발생할 때 각 객체들은 GC 횟수를 기록하는 age bit를 가지고 있다. Minor GC가 발생할 때 age bit 가 1씩 증가되며, 정해진 설정값을 초과하게 되는 경우에 Old영역으로 이동된다. ( Survivor영역의 메모리가 부족할 경우에는 예외로 Old로 바로 넘어간다. )

Old 영역에서 발생하는 GC의 경우 Major GC 또는 Full GC라고 부른다.

Major GC의 경우 Young 영역에서 객체들이 계속 넘어와 Old 영역도 메모리가 부족해지면 발생하게 된다. Minor GC의 경우 GC가 짧은 시간 내로 끝나지만 Major GC의 경우 보통 10배 이상의 시간이 소요된다.

Permanent (Perm 영역)

 메타정보가 기록된 곳이라 보면 된다. Java 8 이후 Perm 영역이 Metaspace영역으로 전환되었고 기존 Perm영역은 삭제되었다. Metaspace영역의 경우 Heap영역이 아닌 Native메모리 영역으로 취급하게 된다.
( 메타정보를 Metaspace영역으로 옮겨 Perm 사이즈 제한을 없앤 것이다 )

동작 방식

1. STW ( Stop the World )
2. Mark And Sweep

1. STW (Stop the World)

 Stop The World는 GC를 진행하는 스레드를 제외한 모든 스레드를 멈추는 상태를 칭한다. GC작업이 완료되면 다시 멈췄던 스레드를 재개시킨다. 스레드가 모두 멈추게 되면 애플리케이션 또한 멈추기 때문에 Stop the World의 시간을 최소화시키도록 해야 한다.
어떠한 GC알고리즘을 사용해도 STW 상태는 피할 수 없으나, GC튜닝을 통해 최소한의 시간으로 줄일 순 있다.

2. Mark And Sweep

 Stop the World를 통해 모든 스레드를 멈추고 GC는 모든 객체를 스캔하면서 각각 어떤 객체를 참조하고 있는지 탐색한다.
이러한 과정에서 사용되고 있는 메모리를 식별하는 게 Mark이다. 이후 Mark가 되지 않은 객체들을 제거하는데 이 과정을 Sweep이라 하여 합친 단어인 Mark And Sweep이라 부른다.

GC 알고리즘 종류

1. Serial GC
2. Parallel GC
3. Parallel old GC
4. CMS(Concurrent Mark & Sweep) GC
5. G1 GC(Garbage First GC)


 이러한 GC 알고리즘이 존재하며, GC알고리즘의 경우 상세 내용은 다음 포스팅에서 마저 진행하도록 하겠다.

- 추가 -
 자바에서 코드로도 가비지 컬렉션이 일어나게 할 수 있다 ( System.gc()를 사용하면 가능하지만 사용하지 않는 것이 좋다. 
이런 이유를 잘 설명해 놓은 블로그가 있어 적어둔다.)
 - https://codingdog.tistory.com/entry/java-systemgc-%ED%95%A8%EC%88%98-%EC%93%B0%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC-%ED%95%A0-%EC%A0%95%EB%8F%84%EB%A1%9C-%EB%AC%B4%EA%B2%81%EB%8B%A4

 

Reference

https://tecoble.techcourse.co.kr/post/2021-08-30-jvm-gc/ 
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

 

Comments