[JAVA] GC(가비지 콜렉터)란?

유존돌돌이·2022년 2월 22일
0

JAVA

목록 보기
18/22
post-thumbnail

GC(가비지 콜렉터)란?

  • 자바에서는 메모리를 GC라는 알고리즘을 통해서 관리하기 때문에 개발자가 메모리를 처리하기 위한 로직을 만들 필요가 없고, 만들어서도 안된다.
  • 자바에서 쓰레기는 객체이다. 하나의 객체는 메모리를 점유하고, 필요하지 않으면 메모리에서 해제해야한다.
  • 예를들어 a라는 객체가 생성되어 메모리의 한부분을 점유하게 되고, 특정 메소드를 처리한 후 종료가 되어 더이상 필요가 없다면 a는 쓰레기가 된다.
  • 이 쓰레기 객체를 효과적으로 처리하는 작업을 GC라고 한다.

GC의 원리

GC작업을 하는 가비지 콜렉터는 다음의 역할을 한다.

  1. 메모리 할당
  2. 사용중인 메모리 인식
  3. 사용하지 않는 메모리 인식

GC를 해도 더 이상 사용 가능한 메모리가 존재하지 않으면 OOM(Out Of Memory) 발생한다.
그렇게 되면 WAS가 다운될 수 있다. 즉 행(Hang) 상태가 되어 요청을 처리 못하는 상태가 된다.

JVM영역

JVM의 메모리는 크게 아래와 같이 나뉘어 있다.
1) Heap : 객체 인스턴스 저장 영역
2) Method Area : 클래스의 구조를 메타데이터로 갖고 있으며 메서드의 코드 저장
2) Stack : 로컬 변수, 중간 연산 결과들이 저장되는 영역
3) PC Registers : 스레드가 현재 수행할 스택 프레임의 주소 저장
4) Native Method Stacks : C / C++등 Low Level코드 실행하는 스택

Heap, Method Area : 모든 쓰레드가 공유
Stack, PCR, NMS : 쓰레드별 고유의 영역

이 중 가비지콜렉터에서는 힙 메모리를 다루게 된다.

Heap은 Young, Old, Perm 세 영역으로 나뉜다.
Perm (permanent generation) 영역은 클래스와 메소드 정보와 같이 자바 언어레벨에서 사용되지 않음
우리가 고려해야 하는 부분은 young(Edend, Survivor1/2), Old(메모리) 총 4개를 보자.

GC 발생 시나리오

1) 새로 생성한 대부분의 객체는 Eden 영역에 위치한다.
2) Eden 영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다.
3) Eden 영역에서 GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역으로 객체가 계속 쌓인다.
4) 하나의 Survivor 영역이 가득 차게 되면 그 중에서 살아남은 객체를 다른 Survivor 영역으로 이동한다. 그리고 가득 찬 Survivor 영역은 아무 데이터도 없는 상태로 된다.
5) 이 과정을 반복하다가 계속해서 살아남아 있는 객체는 Old 영역으로 이동하게 된다.

즉, Survivor 영역 중 하나는 반드시 비어 있는 상태로 남아 있어야 한다. 만약 두 Survivor 영역에 모두 데이터가 존재하거나, 두 영역 모두 사용량이 0이라면 여러분의 시스템은 정상적인 상황이 아니라고 생각하면 된다.

GC(가비지 콜렉터)의 종류

마이너 GC : Young 영역에서 발생하는 GC
메이저 GC : Old 영역이나 Perm 영역에서 발생하는 GC

4가지 GC(가비지 콜렉터) 방식

  1. Serial Collector (이하 시리얼 콜렉터)
  2. Parallel Collector (이하 병렬 콜렉터)
  3. Parallel Compacting Collector (이하 병렬 컴팩팅 콜렉터)
  4. Concurrent Mark-Sweep (CMS) Collector (이하 CMS 콜렉터)

1. 시리얼 콜렉터

Young 영역과 Old 영역이 시리얼하게(연속적으로) 처리되며 하나의 CPU를 사용한다.
SUN 에서는 이를 Stop the world라고 표현했는데, 콜렉션이 실행될때 어플리케이션이 중단된다.

1) 일단 살아있는 객체들은 Eden 영역에 할당
2) Eden 영역이 꽉차게 되면 To Survivor 영역(비어있는 영역)으로 살아 있는 객체가 이동한다.
3) Survivor 영역에 들어가기에 너무 큰 객체는 바로 Old 영역으로 이동
4) From Survivor 영역에 있는 살아 있는 객체는 To Survivor 영역으로 이동
5) To Survivor 영역이 꽉 찼을 경우, Eden 영역이나 From Survivor 영역에 남아 있는 객체들은 Old 영역으로 이동.

이 이후에 Old 영역이나 Perm 영역에 있는 객체들은 Mark-sweep-compact 콜렉션 알고리즘으로 처리된다.
이 알고리즘에 대해서 간단하게 말하면, 안 쓰는 거 표시해서 삭제하고 한 곳으로 모으는 알고리즘이며, 아래와 같다.

Mark-sweep-compact 알고리즘

Step

1) Old 영역으로 이동된 객체들 중 살아 있는 개체를 식별합니다. (Mark)
2) Old 영역의 객체들을 훑는 작업을 수행하여 쓰레기 객체를 식별합니다. (Sweep)
3) [필수아님] 필요 없는 객체들을 지우고 살아 있는 객체들을 한 곳으로 모은다 (Compact)

특징

1) 의도적으로 GC를 실행시켜야지만 unreachable GC 할 수 있다.
2) 어플리케이션 실행과 GC실행이 병행된다.

시리얼 콜렉터는 일반적으로 클라이언트 종류의 장비에서 많이 사용된다.
대기 시간이 많아도 크게 문제되지 않는 시스템에서 사용된다는 의미이다. (사실상 운영에서 쓰기는 어려움)

2. 병렬 콜렉터

다른 CPU가 대기 상태로 남아 있는 것을 최소화
시리얼 콜렉터와 달리 Young 영역에서의 콜렉션을 병렬(Parallel)로 처리
많은 CPU 를 사용하기 때문에 GC의 부하를 줄이고 애플리케이션의 처리량을 증가
Old 영역의 GC는 시리얼 콜렉터와 마찬가지로 Mark-Sweep-Compact 콜렉션 알고리즘을 사용

3. 병렬 Old 콜렉터

병렬 콜렉터와 다른 점은 Old 영역 GC에서 새로운 알고리즘을 사용
Young 영역에 대한 GC는 병렬 콜렉터와 동일하지만, Old 영역의 GC는 다음의 3단계를 거치게 됩니다.

1) Mark 단계 : 살아 있는 객체를 식별하여 표시해 놓는 단계
2) Summary 단계 : 이전에 GC를 수행하여 컴팩션된 영역에 살아 있는 객체의 위치를 조사하는 단계
3) Compact 단계 : 컴팩션을 수행하는 단계. 수행 이후에는 컴팩션된 영역과 비어 있는 영역 정리.

병렬 콜렉터와 동일하게 이 방식도 여러 CPU를 사용하는 서버에 적합하며, GC를 사용하는 스레드 개수는 -XX:ParallelGCThreads=n 옵션으로 조정 가능.

4. CMS 콜렉터

1) Initial Mark 단계에서는 클래스 로더에서 가장 가까운 객체 중 살아 있는 객체만 찾는 것으로 끝낸다. 따라서, 멈추는 시간은 매우 짧다.
2) Concurrent Mark 단계에서는 방금 살아있다고 확인한 객체에서 참조하고 있는 객체들을 따라가면서 확인한다. 이 단계의 특징은 다른 스레드가 실행 중인 상태에서 동시에 진행된다는 것이다.
3) Remark 단계에서는 Concurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다.
4) Concurrent Sweep 단계에서는 쓰레기를 정리하는 작업을 실행한다. 이 작업도 다른 스레드가 실행되고 있는 상황에서 진행한다.

stop-the-world 시간이 매우 짧다. 모든 애플리케이션의 응답 속도가 매우 중요할 때 CMS GC를 사용하며, Low Latency GC라고도 부른다.
하지만 Compaction 단계가 기본적으로 제공되지 않기 때문에 조각난 메모리가 많아 Compaction 작업을 실행하면 다른 GC 방식의 stop-the-world 시간보다 stop-the-world 시간이 더 길기 때문에 Compaction 작업이 얼마나 자주, 오랫동안 수행되는지 확인해야 한다.

5. CMS 콜렉터

G1는 대용량 메모리가 있는 멀티 프로세서 시스템을 위한 GC로 빠른 처리와 그에 따라 짧은 Stop The World를 위해 설계 되었다.
G1 GC는 Heap Area를 Young, Old영역에 대해서 명확하게 물리적으로 구분짓지 않고 동적으로 관리를 한다.
Heap Area를 물리적인 Region 으로 구분하고 있다.
Eden Region, Survivor Region, Old region

[Source]
https://12bme.tistory.com/57
https://mellowp-dev.tistory.com/4
https://blog.ycpark.net/entry/JAVA%EC%9D%98-GC%EC%9D%98-%EC%A2%85%EB%A5%98-%EB%B0%8F-%ED%8A%B9%EC%A7%95
https://www.youtube.com/watch?v=FMUpVA0Vvjw

0개의 댓글