본문 바로가기

Backend Study/Java

[JAVA] Garbage Collection

1. 가비지 컬렉션이란? 

가비지란 쉽게 말하면 유효하지 않은 메모리이다. C나 C++에서는 프로그래머가 수동으로 메모리 할당과 해제를 일일이 해줘야한다. 

반면 자바는 JVM에 있는 가비지 컬렉터가 메모리 관리를 도와주고 있다. 따라서 개발자는 메모리 누수 문제는 고려하지 않고 개발에만 집중할 수 있다. 

 

가비지 컬렉션 (Garbage Collection)은 GC라고 불리기도한다. 자바의 메모리 관리 방법중 하나로 JVM의 Heap 영역에서 동적으로 할당했던 메모리 중에서 필요없는 영역을 주기적으로 삭제하는 프로세스이다.

 

* Heap 이란 ? 

 

[JAVA] 힙 메모리 사용율

1. 자바의 힙 공간이란? 자바 프로그램이 시작되면 JVM 즉 Java Virtual Machine이 운영 체제에서 일부 메모리를 가져온다. JVM은 모든 요구사항에 이 메모리를 사용하며 이 메모리의 일부를 JAVA 힙 메모

gyu-ree.tistory.com

 

개발자 입장에서는 언제 해제되는지 알 수 없고, GC가 동작하는 동안에 다른 동작이 멈추기 때문에 오버 헤드가 발생할 수 있다. 

정말 실력있는 개발자라면 가비지 컬렉션의 동작에 대해서 이해하고, 자신의 서비스에 알맞은 가바지 컬렉터를 선택하고 튜닝할 수 있어야한다.

 

2. 가비지 컬렉션의 대상이 되는 객체들

메모리는 크게  Method Area, Stack Area, Heap Area로 나누어져있다.

객체들은 실질적으로 Heap 영역에서 생성되고, Method Area나 Stack Area 등에서는 생성된 객체의 주소만 참조하는 형식으로 구성된다.  

아래사진처럼 특정 이벤트들로 인하여 Heap Area 객체의 메모리 주소를 가지고 있는 참조 변수가 삭제되는 현상이 발생하면 빨간색 객체처럼 Heap 영역에서 어디서든 참조하고 있지 않은 객체들이 발생한다. 이러한 것들을 주기적으로 가비지 컬렉터가 제거해주는 것이다. 

 

Person person = new Person("Liya");
person.sayHello();

person = new Person("min");
person.sayHello();

위 코드에서 min 객체가 생성되고 참조하면서,  liya 객체를 참조하는 변수가 사라진다. 이 객체는 가비지로 판단된다.

 

3. Stop-the-world

가비지 컬렉터는 종종 메모리 공간 회수를 위해서 자바의 실행을 멈춘다. 이른 어떤 서비스에서는 곤란한 상황을 만들기도 한다. 

그래서 GC 튜닝이 필요하고, 이는 Stop-the-world 시간을 줄이는 것을 의미한다. 

GC가 완료된 이후에 다시 스레드가 실행되도록 한다. 

4. Weak Generation Hypothesis

가비지 컬렉션이 일어날 때마다 JVM의 힙 영역 전체를 스캔하는 동작은 매우 비효율적이다.

오라클의 HotSpot JVM 등의 가상머신은 힙 메모리 영역을 Young Generation 영역과, Old Generation 영역으로 구분해서 사용한다. 

 

weak Generational Hypothesis는 다음과 같다.

- 대부분의 객체들은 생성된 이후 짧은 시간안에 Unreachable 상태가 된다. 

- 생성된지 오래된 객체에서 방금 생성된 객체로의 참조는 아주 적다.

 

이에 따르면 대부분의 객체는 Young Generation 영역에서 생성되었다가 사라지기를 반복하는데, 여기서 객체가 회수되는 작업을 Minor GC라고 한다. 가비지 컬렉션의 동장이 Old Generation까지 스캔해서 가비지를 찾지 않도록해서 더욱 짧은 Stop-the-world 시간안에 메모리를 회수할 수 있도록 한다. Young Generation 영역에서 몇 번의 Minor GC를 겪으며 살아남은 객체가 Old Generation으로 옮겨지는 것이다. 

이렇게 객체가 이동하는 것을 Promotion이라고한다. 

 

Old Generation도 가비지 컬렉션이 수행되어야하고, 이는 Minor GC에 비해 발생하는 빈도는 작지만 좀 더 긴 Stop-the-world 시간을 발생시킨다. 

 

5. Young Generation

young generation은 Eden space, Survivor Space0, Survival Space1 3가지 영역으로 나누어진다. 모든 객체는 Eden 영역에서 생성되고, 점차 오른쪽으로 이동한다. 

 

Eden 영역에서 Minor Gc가 일어나면 Eden 영역에서 생성된 객체 중 stack에서의 일부가 메모리에서 제거된다. 

만약 Survivor() 영역에서 GC가 일어났는데 객체가 또 살아남으면 Survivor1 영역으로 이동한다.

 

또 Survivor1로 이동하고, 여기서도 살아남는다면 Old Generation 영역으로 넘어간다.

5. Old Generation

old generation에서는 Major GC가 일어난다. Major GC는 매우 큰 공간이기 때문에 데이터를 지우는데 많은 시간이 걸린다. 부하도 크기 때문에 Major GC가 자주 일어나는 앱에서는 멈추거나 버벅이는 현상이 발생한다. 따라서 Major Gc는 일어나지 않도록 하는게 가장 좋다.

 

 

참고) https://coding-factory.tistory.com/829

https://hbase.tistory.com/209

https://kotlinworld.com/340