지난 글에서 GC에 의미와, GC의 대상
그리고 java에서 GC의 대상을 찾는 [Mark And Sweep] 특징에 대해 알아보았다.
특징 중 첫번째인 "의도적으로 GC를 실행시켜야한다." 는 특징이 있다.
그래서 이번 글에서는 GC의 구동방식이 어떻게 되는지 알아볼 것이다.
설명 할 내용을 아래 그림이 압축적으로 보여준다. 일단 눈에 익혀보자.
Heap 영역
- 가비지 컬렉션에 대상이 되는 공간이다.
- 동적으로 레퍼런스 데이터가 저장되는 공간이다.
객체는 대부분 일회성되며, 메모리에 오랫동안 남아있는 경우는 드물다는 것이다.
이러한 특성을 이용해 JVM 개발자들은 보다 효율적인 메모리 관리를 위해, 객체의 생존 기간에 따라 물리적인 Heap 영역을 나누게 되었고 Young 과 Old 총 2가지 영역으로 설계하였다.
Survivor 0
또는 Survivor 1
둘 중 하나에는 꼭 비어 있어야 하는 것이다.이렇게 하나의 힙 영역을 세부적으로 쪼갬으로서 객체의 생존 기간을 면밀하게 제어하여 가비지 컬렉터(GC)를 보다 정확하게 불필요한 객체를 제거하는 프로세스를 실행하도록 한다.
[Java8 에서의 Permanent 영역]
Permanent는 직역하면 영구적인 세대의 의미로서, 생성된 객체들의 정보의 주소값이 저장된 공간이다. 클래스 로더에 의해 load되는 Class, Method 등에 대한 Meta 정보가 저장되는 영역이고 JVM에 의해 사용된다. Java 7 까지는 힙 영역에 존재했지만 Java 8 버전 이후에는 Native Method Stack에 편입되게 된다.
Java8부터는 MetaSpace영역이 추가되었다. 이 영역에서는 Class들의 Metadata가 저장되는 곳이다.
- java 7 HotSpot JVM
<----- Java Heap -----> <--- Native Memory ---> +------+----+----+-----+-----------+--------+--------------+ | Eden | S0 | S1 | Old | Permanent | C Heap | Thread Stack | +------+----+----+-----+-----------+--------+--------------+ <---------> Permanent Heap S0: Survivor 0 S1: Survivor 1
- Java 8 HotSpot JVM
<----- Java Heap -----> <--------- Native Memory ---------> +------+----+----+-----+-----------+--------+--------------+ | Eden | S0 | S1 | Old | Metaspace | C Heap | Thread Stack | +------+----+----+-----+-----------+--------+--------------+
-> 이 부분도 더 찾아볼 것!
Young Generation 영역에서 발생되는 GC를 Minor GC라 함.
처음 생성된 객체는 Young Generation 영역의 일부인 Eden 영역에 위치
객체가 계속 생성되어 Eden 영역이 꽉차게 되고 Minor GC가 실행
Mark 동작을 통해 Reachable 객체를 탐색
[age]
- Survivor 영역에서 객체의 객체가 살아남은 횟수를 의미하는 값이며, Object Header에 기록된다.
- 만일 age 값이 임계값에 다다르면 Promotion(Old 영역으로 이동) 여부를 결정한다.
- JVM 중 가장 일반적인 HotSpot JVM의 경우 이 age의 기본 임계값은 31이다.
- 객체 헤더에 age를 기록하는 부분이 6 bit로 되어 있기 때문이다.
- Survivor 영역의 제한 조건으로
- Survivor 영역 중 반드시 1개는 사용되어야 하고, 나머지는 비어 있어야 한다.
- 만약 두 Survivor 영역에 모두 데이터가 존재하거나, 모두 사용량이 0이라면 현재 시스템이 정상적인 상황이 아니라는 반증이 된다.
또다시 Eden 영역에 신규 객체들로 가득 차게 되면 다시한번 minor GC 발생하고 mark 한다
marking 한 객체들을 비어있는 Survivor 1으로 이동하고 <-(sweep)
GC 종류 | Minor GC | Major GC |
---|---|---|
대상 | Young Generation | Old Generation |
실행 시점 | Eden영역이 가득 찬 경우, Survivor영역이 가득 찬 경우 | Old영역이 가득 찬 경우 |
실행 속도 | 빠르다 | 느리다 |
Minor GC와 Major GC의 비교로써 Major GC의 시간이 오래걸리게 되고, 앞 글에 소개했던 Stop-The-World 문제가 발생하게 된다.
Major GC가 일어나면 Thread가 멈추고 Mark and Sweep 작업을 해야 해서 CPU에 부하를 주기 때문에 멈추거나 버벅이는 현상이 일어나기 때문이다.
따라서 자바 개발진들은 끊임 없이 가비지 컬렉션 알고리즘을 발전 시켜왔다.
이 다음글에서 GC의 알고리즘에 대해 알아보도록 하겠다.
출처: