상세 컨텐츠

본문 제목

[JAVA] GC : Garbage Collection

JAVA

by jeonghojin 2023. 4. 16. 03:13

본문

GC : Garbage Collection

 

자바 메모리 관리 기법 중의 하나로 JVM의 Heap 영역에서 동적으로 할당했던 메모리 영역 중 필요없게 된 메모리 영역을 주기적으로 삭제하는 프로세스

C / C++의 경우 GC가 없어 프로그래머가 직접 fee()함수를 사용하여 메모리를 해제해주어야 한다.

메모리를 해제하지 않게 되면 메모리 누수가 발생하여 프로그램이 종료되거나 문제가 발생할 수 있다.


자바 메모리 관리에 관한 내용은 아래 참고.

https://hojinjeong.tistory.com/240

 

[JAVA] 메모리 관리

Java Virtual Machine(JVM) C / C++에서는 OS 레벨의 메모리에 직접 접근하기 떄문에 free()라느 메소드를 호출하여 할당받았던 메모리를 명시적으로 해제해주어야 한다. *그렇지 않으면 memory leak이 발생. *

hojinjeong.tistory.com

 


GC:Garbage Collection 단점

  • 메모리가 언제 해제되는지 정확히 알 수 없다.
  • GC(Garbage Collection)이 동작하는 동안에는 다른 동작이 멈추기 때문에 오버헤드가 발생한다.

GC 이 동작하는 동안에 다른 동작이 멈추기 떄문에 오버헤드가 발생한다. 이로 인해, GC가 너무 자주 실행되면 소프트웨어 성능 문제가 발생할 수 있다. *Stop-The-World

STW(Stop-The-World)
GC를 실행하기 위해 JVM이 프로그램을 멈추게 하는 현상
GC가 동작하는 동안 GC관련 Thread를 제외한 모든 Thread는 멈추게 되며, 서비스 이용에 차질이 생길 수 있다.

GC:Garbage Collection의 대상

객체들은 실질적으로 Heap 영역에 생성되고 stack 영역에서는 heap 영역에 생성된 객체의 주소만을 참조하는 형식으로 구성된다. 

메소드가 끝나는 등의 특정 이벤트들로 인하여 Heap 영역에 생성된 객체들이 가지고 있던 값들에 대함 참조 변수가 삭제 되면 Heap 영역에서는 어디에서도 참조되지 않는 객체들이 발생하게 된다. 이러한 객체들을 Unreachable 이라고 하며, 주기적으로 GC가 삭제하게 된다.

* Reachable : 객체가 참조하고 있는 상태

* UnReachable : 객체가 참조되고 있지 않은 상태(GC의 대상이 됨)

 


Mark And Sweep 알고리즘

Mark And Sweep 알고리즘은 GC가 동작하는 원리로, 루트에서부터 해당 객체에 접근 가능한지에 대한 여부를 메모리 해제의 기준으로 삼는다.

  • Mark 과정 : Root 로부터 그래프 순회를 통해 연결된 객체들을 찾아내어 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다.
  • Sweep 과정 : 참조하고 있지 않은 객체 즉, Unreachable 객체들을 Heap에서 제거한다.
  • Compact 과정 : Sweep 후에 분산된 객체들을 Heap의 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 압축한다. * GC의 종류에 따라 그렇지 않은 경우도 있음.
GC의 Root Space
Mark And Sweep 방식은 루트로부터 해당 객체에 접근이 가능한지가 해제의 기준이 된다.
JVM GC에서의 Root Space는 Heap 메모리 영역을 참조하는 Stack, Static 변수, method 영역 native method stack 이 된다.

Heap 영역은 효율적인 GC 를 위해 Eden, Survival, Old,Generation으로 나뉜다.

Eden - new 를 통해 생성된 객체가 위치
- 정기적인 쓰레기 수집 후, 살아남은 객체들은 Survival 영역으로 보냄.
survival 0 / survival 1 - 최소 1번의 GC 잇ㅇ 살아남은 객체가 존재하는 영역
- Survival 0 또는 Survival 1 둘 중 하나에는 꼭 비어있어야 한다.
Old Generation - Young 영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역
- Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.
- Old Generation 영역에 대한 Gc를 Major GC 또는 Full GC 라고 한다.

Heap 영역을 세부적으로 나눔으로써 객체의 생존 기간을 세세히 제어하여 GC를 보다 정확하게 불필요한 객체를 제거하는 프로세스를 실행하도록 한다.

Java 8에서의 Permanent
영구적인 세대를 의미. 생성된 객체들의 정보의 주소값이 저장된 공간이다.클래스 로더에 의해 load 되는 Class, Method 등에 대한 메타 정보가 저장되는 영역이고, JVM에 의해 사용된다.
Java 7 까지는 Heap 영역에 존재했지만 Java 8 버전 이후에는 Native Method Stack에 편입되게 된다.

GC 동작 과정

Minor GC 과정

* Minor GC : Young Generation 영역에서 바생하는 GC

Young Generation 영역은 짧게 살아남는 메모리들이 존재하는 공간이다. 모든 객체는 처음 생성될 때 Young Generation 영역에 생성되게 된다.

*Young Generation 영역은 Old Generation 영역에 비해 상대적으로 작기 때문에 메모리상의 객체를 찾아 제거하는데 적은 시간이 걸린다.

 

  • 처음 생성된 객체는 Young Generation 영역의 Eden 영역에 위치한다.
  • 객체가 계속 생성되어 Eden 영역이 가득차게 되면 Minor GC가 실행된다.
  • Mark 동작을 통해 reachable 객체를 탐색한다.
  • Eden 영역에서 살아남은 객체는 1개의 Survival 영역으로 이동한다.
  • Eden영역에서 사용되지 않는 객체(Unreachable)의 메모리를 해제한다.
  • 살아남은 객체는 age값이 1씩 증가한다.
age 값
- survival 영역에서 객체가 살아남은 횟수를 의미하는 값. Object Header에 기록
- age 값이 임계값에 다다르면 Promotion(Old영역으로 이동) 여부를 결정한다.
- JVM 중 가장 일반적인 HotSpot JVM의 경우 기본 임계값은 31이다.
- Object Header 에 age 기록하는 부분이 6bit로 되어있기 떄문이다.
  • 또 다시 Eden 영역에 새로운 객체들로 가득차게 되면 다시 한번 Minor GC가 발생하고 mark 한다.
  • marking 한 객체들을 비어있는 survival 1 으로 이동시키고 sweep 알고리즘 실행한다.
  • 다시 살아남은 모든 객체들은 age가 1씩 증가한다.
  • 이러한 과정을 반복하여 진행한다.

Major GC 과정

 

Old Generation 은 오래 살아남는 메모리들이 존재하는 공간이다. Old Generation 객체들은 Young Generation 에 의해 시작되어 GC 과정 중에 제거되지 않은 경우 age 임계값이 차게되어 이동하게 된 것이다.

 

Major GC는 객체들이 계속 Proomtion 되어 Old 영역의 메모리가 부족해지면 발생하게 된다.

 

* Minor GC : Eden이 가득 찬 경우 발생

* Major GC : Old 영역이 가득 찬 경우 발생

 

  • 객체의 age가 임계값에 도달하게 되면 이 객체들은 Old Generation 으로 이동된다. 이를 Promotion 이라 함.
  • 위 과정이 반복되어 Old Generation 영역의 공간(메모리)가 부족하게 되면 Major GC가 발생하게 된다.

*Old 영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체들을 한꺼번에 삭제한다.

*Old Generation은 Young Generation 에 비해 상대적으로 큰 공간을 가지고 있어, 이 공간에서 메모리 상의 객체 제거에 많은 시간이 걸리게 된다. ( Young 영역에서는 0.5 - 1초 사이에 끝난다면, Old 영역에서는 10 배이상의 시간을 사용하게 된다.) 이 과정에서 Stop-The-World 문제 바생


참고 :

더보기

'JAVA' 카테고리의 다른 글

[JAVA] List 마지막 값으로 덮어 씌워지는 문제  (0) 2023.07.31
[JAVA] 제네릭(Generic)  (0) 2023.05.01
[JAVA] 메모리 관리  (0) 2023.04.14
[Design Pattern] Facade Pattern  (0) 2023.04.06
[Design Pattern] Proxy Pattern : Remote Proxy  (0) 2023.04.02

관련글 더보기