Garbage Collection(GC) 탄생배경
프로그래머가 동적으로 할당한 메모리 영역 중 사용되지 않는 영역을 자동으로 식벼하고 해제하는 기능으로 이 개념은 1959년 존 매카시(Jon McCarthy)가 LISP 언어의 메모리 관리를 위해 처음 도입했다고 알려져있다.
과거 프로그래밍 언어들은 동적 메모리 할당기능이 전혀 없거나, C 계열 언어와 같이 프로그래머가 직접 메모리를 할당 한 뒤 수동으로 해제하는 방식을 사용하였으나 프로그래머의 메모리 관리가 완벽하지 않을 수 있기 때문에 메모리 누수, 이미 해체된 메모리의 재사용, 해제된 메모리를 다시 해제하는 등 실수로 인해 많은 버그와 취약점이 밟생할 수 있었고 재현 불가능한 오류를 발생시키기도 하여, 프로그래머들에게 엄청난 디버깅 난이도를 주었습니다.
Garbage Collection(GC)
가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리방법 중의 하나로 JVM(자바 가상머신)의 Heap영역에서 동적으로 할당했던 메모리 중 필요 없게 된 객체(garbage)를 모아 주기적으로 제거하는 프로세스
장점
- 가비지 컬렉터가 메모리 관리를 대행해주기때문에 한정된 메모리를 효율적으로 사용, 개발자입장에서의 메모리 관리, 메모리 누수의 문제에 대하여 완벽히 관리하지 않고 개발에만 집중가능
단점
- 개발자가 메모리가 언제 해제되는지 정확하게 알 수 없다.
- 가비지 컬렉션이 동작하는 동안에는 다른 동작을 멈추기 때문에 오버헤드(어떤 처리를 하기 위해 들어가는 간접적인처리 시간 · 메모리 등)가 발생한다.
** 위 단점을 Stop-The-World라고 한다
Stop-The-World
GC를 수행하기 위해 JVM이 프로그램 실행을 멈추는 현상을 의미
GC가 작동하는 동안 GC관련 Thread를 제외한 모든 Thread는 멈추게되어 서비스이용에 차질이 생길 수 있다.
예로 익스플로어는 이 가비지 컬랙션을 너무 자주 실행하여 성능에 문제를 일으키는 것으로 악명 높았다.
실시간성이 매우 강조되는 프로그램일 경우 가비지컬렉터에게 메모리를 맞기는 것은 맞지 않을 수 있다.
가비지 컬렉션(GC)의 대상이 되는 객체
가비지 컬렉션은 특정객체가 garbage인지 판단하기 위하여 도달성, 도달능력(Reachability)이라는 개념을 적용.
객체에 레퍼런스가 있다면 Reachable로 구분, 객체에 유효한 레퍼런스가 없다면 Unreachable로 구분하여 제거
GC의 대상이 되는 heap메모리의 구조
JVM의 힙(heap)영역은 동적으로 레퍼런스 데이터가 저장되는 공간으로서, 가비지 컬렉션에 대상이 되는 공간이다.
heap영역은 처음 설계될 때 다음의 2가지 전제로 설계되었다
- 대부분의 객체는 금방 접근 불가능한 상태(Unreachable)가 된다.
- 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.
즉, 객체는 대부분 일회성이며 메모리에 오랫동안 남아있는 경우는 드물다.
이러한 특성을 이용해 JVM 개발자들은 보다 효율적인 메모리 관리를 위해, 객체의 생존기간에 따라 물리적인 heap 영역을 나누게 되었고 Young와 Old 총 2가지 영역으로 설계하였다
가비지 컬렉션(GC)과정
GC는 크게 Young영역과 Old영역으로 나뉘어진다(Perm영역은 Java8 버전 이후에는 Native Method Stack에 편입)
Young 영역
- 새롭게 생성한 객체가 할당(Allocation)되는 영역
- 대부분의 객체가 금방 접근 불가능 상태(Unreachable)가 되기 때문에 많은 객체가 Young영역에 생성되었다. 사라진다.
- Young 영역에 대한 가비지 컬렉션 Minor GC가 발생한다고 말한다.
Young 영역의 구성
- Eden 영역
new를 통해 새로 생성된 객체가 위치.
정기적인 쓰레기 수집 후 살아남은 객체들은 Survivor 영역으로 보냄 - 두개의 Survivor 영역
최소 1번의 GC 이상 살아남은 객체가 존재하는 영역
Survivor 영역에는 특별한 규칙이 있는데, Survivor 0 또는 Survivor 1 둘중 하나에는 꼭 비어있어야 한다.
- 새로 생성된 객체 대부분은 Eden 영역에 위치
- Eden 영역에서 GC가 한번 발생한 후 살아남은 객체는 Survivor영역 중 하나로 이동
- GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor영역에 객체가 계속 쌓임
- 하나의 Survivor영역이 가득 차면 살아남은 객체를 다른 Survivor 영역으로 이동하여 하나의 Survivor 영역을 비워줌
- 이런 GC과정을 통해 살아남은 객체는 Old 영역으로 이동
Old영역
- Young영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역
- Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.
- Old 영역에 대한 가비지 켤렉션(garbage Collection)을 Major GC 또는 Full GC라고 부른다.
가비지컬렉션(GC)의 종류
1. Serial GC
- 서버의 CPU 코어가 1개일 때 사용하기 위해 개발된 가장 단순한 GC
- GC를 처리하는 Threa가 1개 (싱글 쓰레드)여서 가장 Stop-The-World 시간이 길다
- Minor GC는 Mark and Sweep를 사용하고, Major GC는 Mark and Sweep-Compact를 사용한다.
- 보통 실무에서 사용하는 경우는 거의 없다(디바이스 성능이 안좋아서 CPU코어가 1개인 경우에만 사용)
Mark and Sweep
- Mark:사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
- Sweep: Mark 단계에서 사용되지않음으로 식별된 메모리를 해체하는작업
2. Parallel GC
- Java8의 디폴트 GC
- Serial GC와 기본적인 알고리즘은 같지만,Young 영역의 MinorGC를 멀티쓰레드로 수행(Old 영역은 싱글쓰레드 사용)
- Serial GC에 비해 Stop-The-World 시간 감소
3. Parallel Old GC(Parallel Compacting Collector)
- parallel GC를 개선한 버전
- Young 영역과 Old 영역에서도 멀티 Thread로 GC 수행
- 새로운 가비지 컬렉션 청소방식인 Mark-Summary-Compact 방식을 이용
4. CMS GC(Concurrent Mark Sweep)
- 어플리케이션의 쓰레드와 GC쓰레드가 동시에 실행되어 Stop-The-World 시간을 최대한 줄이기 위해 고안된 GC단, GC과정이 매우 복잡해짐
- GC 대상을 파악하는 과정이 복잡한 여러단계로 수행되기 때문에 다른 GC대비 CPU사용량이 높다
- 메모리 파편화 문제
- CMS GC는 Java9 버전부터 deprecated되었고 결국 Java14에서는 사용이 중지
5. G1GC(Garbage First)
- CMS GC를 대체하기 위하여 jdk7 버전에서 최초로 release된 GC
- Java9+ 버전의 디폴트 GC로 지정
- 4GB 이상의 힙메모리, Stop-The-World 시간이 0.5초 정도 필요한 상황에 사용(Heap가 너무 작을경우 미사용 권장)
- 기존의 GC알고리즘에서는 heap영역을 물리적으로 고정된 Young/Old영역으로 나누어 사용하였지만,G1GC는 완전히 이러한 개념을 뒤엎는 Region이라는 영역으로 체스같이 분할하여 상황에 따라 Eden, Survivor, Old 등 역할을 고정이 아닌 동적으로 부여
- Garbage로 가득찬 영역을 빠르게 회수하여 빈 공간을 확보하므로, 결국 GC 빈도가 줄어드는 효과를 얻게되는 원리
- pause 시간을 예측하기 어려움 특정 상황에서는 pause시간을 예측하기 어려울 수 있다 특히, 높은 메모리 사용량이나 급격한 객체 생성/삭제 패턴이 있는 어플리케이션에서는 예상하지 못한 긴 pause시간이 발생할 수 있음
6. Shenandoah GC
- Java12에 release
- 레드햇에서 개발한 GC
- 기존 CMS가 가진 단편화, G1이 가진 Pause의 이슈를 해결
- 강력한 Concurrency와 가벼운 GC로직으로 heap 사이즈에 영향을 받지 않고 일정한 pause 시간 소요가 특징
7. ZGC (Z Garbage Collector)
- Java 15에 release
- 대량의 메모리(8MB ~ 16TB)를 low-latency로 잘 처리하기 위해 디자인된 GC
- G1의 Region처럼 ZGC는 ZPage라는 영역을 사용하며, G1의 Region은 크기가 고정인데 비해, ZPage느 2mb 배수로 동적 운영됨. (큰 객체가 들어오면 2^로 영역을 구성해서 처리)
- ZGC가 내세우는 최대 장점 중 하나는 힙 크기가 증가하더라도 Stop-The-World 시간이 절대 10ms를 넘지 않음
[결과]
Garbage Collector은 쓰레기 값을 정리하며 Eden 영역 -> servivor 영역 -> old영역으로 이동하며 young 영역과 old 영역의 가장 큰 차이점은 Stop The Wolrd가 old영역에는 없다는 것이다.
[느낀점]
Garbage Collector가 메모리 관리를 하여 개발자가 메모리 관리외의 다른 부분에 신경을 쓸 수 있게 되어 좋은 점도 있지만 GC가 자주발생하게되면 Stop The World가 자주 발생하게 되는데 이에따른 성능저하에 대한 관리에대하여 공부를 해야겠다
참고사이트
☕ 가비지 컬렉션 동작 원리 & GC 종류 💯 총정리
Garbage Collection(GC) 이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객
inpa.tistory.com
https://s-y-130.tistory.com/111
[JAVA] 가비지 컬렉션(Garbage Collection) 동작 원리 & GC 종류
가비지 컬렉션(Garbage Collection)이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 영역 중 필요 없
s-y-130.tistory.com
https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html
Java 의 GC는 어떻게 동작하나? - J's log
Java 프로세스가 동작하는 과정에서 GC는 불필요한 또는 더이상은 사용하지 않는 객체들을 메모리에서 제거함으로써, Java 프로세스가 한정된 메모리를 효율적으로 사용할 수 있게 해준다. 또한 JV
mirinae312.github.io
Garbage Collector, 프로그램의 스캐빈저
오늘은 프로그래머의 뒤처리를 담당해 주는 가비지 컬렉터(Garbage Collector, GC)에 대해서 알아보도록 합시다. 메모리 관리 방법 중 하나인 가비지 컬렉션(Garbage Collection)은 프로그래머가 동적으로
theworldaswillandidea.tistory.com
'Java' 카테고리의 다른 글
예외가 생겼으니 처리를하려면: 예외처리(Exception Handling) 3가지 방법 (0) | 2024.07.07 |
---|---|
둘이 같은 게 아닌가?(2): 인터페이스와 추상클래스 (0) | 2024.07.07 |
둘이 같은게 아닌가?: 라이브러리와 프레임워크 (0) | 2024.07.07 |
자바 가상머신은 왜 있는거지?: JVM(JAVA Virtual Macchine) (0) | 2024.07.02 |
인터프리터의 느린 방식의 대처방안: JIT(Just In Time) 컴파일러 (1) | 2024.06.30 |