메모리 관리

Jeong Gyejin·2023년 3월 1일
0

JAVA

목록 보기
12/18

메모리 관리

자바의 메모리 관리는 가상 머신인 JVM에서 진행이 됩니다.
메모리 관리라는 까다로운 부분을 자바 가상머신에 모두 맡겨버리는 것입니다.
프로그램 실행시 JVM 옵션을 주어서 OS에 요청한 사이즈 만큼의 메모리를 할당 받아서 실행하게 되며, 할당받은 이상의 메모리를 사용하게 되면 에러가 나면서 자동으로 프로그램이 종료가 됩니다.
그러므로 현재 프로세스에서 메모리 누수가 발생하더라도 현재 실행중인 것만 죽고, 다른 것에는 영향을 주지 않는다.
이렇게 자바는 가상머신을 사용함으로써 OS 레벨에서의 memory leak 은 불가능하게 된다는 장점이 있다.

자바가 메모리 누수현상을 방지하는 또 다른 방법이 가비지 컬렉션이다.

Garbage Collector

Garbage collector란 동적으로 할당한 메모리 영역 중 사용하지 않는 영역을 탐지하여 해제하는 기능을 이야기 합니다.
여기서 동적으로 할당한 영역이란?
모든 object타입의 데이터가 할당되어있으며, stack영역에서 참조되어있는 실제값들이 저장되어 있는 heap영역을 이야기합니다.

Garbage Collector 과정

heap의 영역 중 eden, survival 0, survival 1의의 영역이 모두 사용되면 발생합니다.
Mark and Sweep의 과정이라고도 하며, Stack의 모든 변수들과 reachable object를 스캔하면서 각각 어떤 객체들을 참조하고 있는지 찾아서 마킹합니다.
그 후 마킹되지 않은 객체들을 heap 영역에서 제거합니다.

heap의 구조


heap의 구조는 위 그림과 같이 Eden영역, survival 0 영역, survival 1영역, old generatation 영역으로 나누어져 있습니다.

  • Eden영역: 처음 새로운 객체가 참조되어 생성되어 있는 곳입니다.
  • Survival 0영역: Eden영역이 가득차게 된 이후 살아남은 reachable 객체가 이동하여 쌓이는 곳입니다.
  • Survival 1영역: Survival 0영역이 가득 찼을 경우 Garbage Collector과정이 이루어지고 살아남은 reachable 객체들이 이동하고 이동한 객체들은 age값이 1씩 증가합니다.
  • 그 이후에 Eden영역에서 Garbage Collector가 이루어지게 된다면 Survival 1영역에 reachable 객체들이 쌓이게 되며 Survival 1영역이 가득차게 된다면 위와 같은 과정을 통해서 Garbage Collector 과정을 거쳐서 Survival 0 영역으로 이동하며 age 값들이 증가하며 반복하게 됩니다.

    즉, Survival 0 혹은 1 영역 둘 중 한 개에만 객체들이 쌓이게 되며, 해당 영역에서 진행되는 Garbage Collector 과정을 minor GC라고 합니다.

  • 위와 같은 과정을 거쳐서 특정 age값에 도달하게 된다면 이 값들은 Old Generation으로 이동하게 되는데 이 과정을 Promotion이라고 합니다.

    Old Generation에서도 객체가 가득차서 Garbage Collector가 이루어지게 된다면 이 과정을 major GC라고 합니다.

Garbage Collector의 종류

1. Serial Garbage Collector


출처: https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html

  • 가장 단순한 방식의 GC로 싱글 스레드(스레드 1개)로 동작한다.
  • 싱글 스레드로 동작하여 느리고, 그만큼 Stop The World 시간이 다른 GC에 비해 길다.
  • Mark - compact & Compact 알고리즘을 사용(Mark and Sweep과정 이후 쪼개진 데이터를 한 곳에 모으는 알고리즘)

2. Parallel Garbage Collector

  • Java 8의 default GC입니다.
  • Young 영역의 GC를 멀티 스레드 방식을 사용하기 때문에, Serial GC에 비해 상대적으로 Stop The World 가 짧습니다,
    • Stop The World: Garbage Collector를 실행하기 위해서는 JVM 애플리케이션 실행을 멈춰야 합니다. 이 과정을 Stop The World라고 합니다. 만약 Stop The World가 발생하게 되면 Garbage Collector를 실행하는 스레드를 제외한 나머지 스레드는 모두 작업을 멈추고 Garbage Collector가 완료된 이후에 다시 실행 됩니다.

3. Concurrent Mark Sweep Garbage Collector(CMS GC)

  • Stop The World로 애플리케이션이 멈추는 현상을 줄이기 위해서 만든 GC로 속도가 향상되어 응답이 빠릅니다.
  • 하지만 메모리와 CPU를 더 많이 사용하며, 압축하는 단계가 제공되지 않습니다.
  • Reachable 객체를 한번에 찾지 않고 4단계로 나누어서 찾는 방식입니다.

    출처: https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html
  1. Initial Mark: GC Root가 참조하는 객체만 마킹 (stop-the-world 발생)
  2. Concurrent Mark: 참조하는 객체를 따라가며, 지속적으로 마킹. (stop-the-world 없이 이루어짐)
  3. Remark: concurrent mark 과정에서 변경된 사항이 없는지 다시 한번 마킹하며 확정하는 과정. (stop-the-world 발생)
  4. Concurrent Sweep: 접근할 수 없는 객체를 제거하는 과정 (stop-the-world 없이 이루어짐)

4. Garbage First Garbage Collector (G1GC)

  • Java 9+ 의 default GC입니다.
  • 현재 GC 중 stop-the-world의 시간이 제일 짧습니다.
  • CMS GC를 개선하여 만든 GC로 위에서 살펴본 GC와는 다른 구조를 가집니다.
  • 각 영역을 region 영역으로 나누어 GarbageCollector가 일어날 때 전체 영역을 탐색하지 않으며 압축하는 단계를 사용합니다.

    출처: https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html
  1. Heap을 Region이라는 일정한 부분으로 나눠서 메모리를 관리
  2. 전체 Heap에 대해서 탐색하지 않고 부분적으로 Region 단위로 탐색하여, 각각의 Region에만 GC가 발생.
profile
항상 더 나은 개발자가 되기 위해서 끊임없이 공부하고 학습하면서 성장하는 사람이 되겠습니다.

0개의 댓글