Skip to content

GC(with Java Heap)

JungHyunLyoo edited this page Jun 15, 2020 · 6 revisions

Heap이란

  • 인스턴스와 배열이 동적으로 생성되는 공간.

  • 생성에 필요한 인스턴스와 배열의 메타 정보는 Heap 내의 Method Area에서 얻어온다.

  • 모든 Thread가 공유하기 때문에 동기화 문제가 발생할 수 있다.

  • Garbage Collection의 대상이 되는 영역.

  • 개발자는 객체를 제거하기 위해 별도의 코드를 작성할 필요가 없고 오히려 부작용만 낳을 가능성이 큼. GC에 맡기는 것이 좋다

Heap 구성

Java 8 이전
Java 8 이전에는 Metaspace라고 지칭된 영역 대신에 PermGen(Permanat Generation Space)라고 
불리는 영역이 존재했었다. 이 영역은 클래스의 메타 정보와 GC에서 살아남은 객체들, 그리고 
static 변수들의 '값'을 가지고 있는 공간이다. 생각해보면, Method Area와 역할이 동일해보인다. 
사실 Method Area는 논리적으로(logicaly) PermGen 안에 포함된다. 

그리고 JVM을 실행할 때, -XX:PermSize : 초기 Perm size -XX:MaxPermSize : 최대 Perm size
이러한 옵션을 추가하면 PermGen의 사이즈를 설정할 수 있다. 
(아마 Method Area의 크기도 특정한 비율로 같이 조절되지 않을까 싶다)

또한 Heap처럼 PermGen도 메모리 공간 오류가 발생할 수 있다.
- Exception in thread “main”: java.lang.OutOfMemoryError: Java heap spac
- Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space
Java 8 이후 
PermGen 영역이 사라졌다. 그리고 PermGen이 담당하던 역할을 다음과 같이 분리했다. 
- 수정될 필요가 있는 데이터(static Object나 상수화된 String Object)
- 수정될 필요가 없는 데이터(class, method 등의 메타데이터)

수정될 필요가 있는 데이터는 Heap으로 옮겨 최대한 GC의 대상이 되도록 했고 
수정될 필요가 없는 데이터는 OS가 Native Memory에서 직접 관리하도록 위임했다. 
이 Memory Area를 Metaspace라고 부른다. 이 변화는 PermGen영역의 size 제한을 
없애기 위한 것이 목적이다. Metaspace가 Native memory에 위치함으로써 
개발자는 영역 확보의 상한을 크게 의식할 필요가 없어지게 되었다.

Heap의 자세한 구성은 아래 GC의 동작을 이해하면 더욱 쉽게 알 수 있다.

Garbage Collection

  • 개발자는 Heap을 자유롭게 사용하고 더이상 사용하지 않는 오브젝트들은 GC를 담당하는 프로세스가 자동으로

메모리에서 제거하도록 하는 것이 GC의 기본 개념.

  • Heap의 인스턴스 중 Thead의 JVM stack에서 도달할 수 없는 것들(Unreachable)이 GC의 대상.

중요한건, 도달할 수 없는 것들을 pick 하는 것이 아니라 도달할 수 있는 것들을 pick한 후 나머지들을 메모리에서 제거한다.

이 방식을 Mark and Sweep 이라고 한다.

Mark
GC가 JVM stack의 모든 변수를 스캔하면서 각각이 힙 메모리의 어떤 인스턴스를 
참조하고 있는지 찾음. 발견된 인스턴스 또한 어떤 인스턴스를 참조하고 있는지 찾음.
이 작업이 수행되면 모든 스레드는 중단되는데, 이를 'stop the world'라고 부름
(System.gc() 호출을 가볍게 보면 안될것)
Sweep
Mark되지 않은 인스턴스들을 제거

Garbage Collection 실행 과정(with Heap Memory)

Young Generation

- Eden 
인스턴스들이 최초로 생성되는 공간. 이 영역이 가득차게 되면 Reachable 인스턴스들은 
Survivor 0 으로 옮겨진다. 이를 MinorGC라고 한다. 
반면 Unreachable 인스턴스들은 MinorGC가 실행될 때 삭제된다.

- Survivor 0 
MinorGC가 한번 발생한 뒤 두번째 발생하게 되면 기존에 Survivor 0에 있었던 인스턴스 중 
Reachable 인스턴스들은 Survivor 1로 옮겨지고Unreachable 인스턴스들은 삭제된다. 
옮겨질 때 각 인스턴스이 가지고 있는 고유의 age값이 증가한다.

- Survivor 1
MinorGC가 세번 째 발생하게 되면 Survivor 1에 있었던 인스턴스들이 다시 Survivor 0로 
옮겨지고 삭제된다. 이때도 각 age값이 증가한다. 인스턴스들이 Survivor 0 <-> Survivor 1 이동을 
반복하고, 각 age값들이 특정 기준을 넘어서면 그 인스턴스들은 Old Generation으로 이동한다. 
이를 Promotion 단계라고 한다.
- Old Generation
Promotion 단계가 반복되면서 Old Generation이 가득 차게 되면 MajorGC가 발생하게 된다
Clone this wiki locally