티스토리 뷰
이번에 소개할 내용은 GC(Garbage Collection)가 HotSpot VM에서 작동하는 기본 사항을 설명한다. 프로그램의 성능을 생각하는 개발자라면 GC(Garbage Collection)가 어떻게 처리되는지 기본 지식을 갖고 있어야 한다. GC(Garbage Collection)에 대해서 반드시 암기하고 숙지해야 자바 개발을 할 수 있는 것은 아니다. 자신이 만든 자바 프로그램의 성능을 생각하는 프로그래머라면, GC(Garbage Collection)가 어떻게 처리되는지 기본 지식을 갖고 있는 것이 좋다.
GC(Garbage Collection)에 관심을 갖고 관련 내용을 찾을 정도면 프로그래머로써의 한 단계 레벨업을 꿈꾸시는 분들로 생각된다.
우선 JAVA 메모리 스택&힙 영역에 대해 기본적으로 알고 접근해야 한다.
[엔지니어링/성능과 튜닝] - [성능과 튜닝] JAVA 메모리 관리 (스택&힙)
Automatic Garbage Collection
GC(Garbage Collection)은 Heap Memory 영역에서 사용 중인 객체, 사용하지 않는 객체를 식별하여 자동으로 삭제하는 프로세스를 가지고 있다. 사용 중인 객체 또는 참조되는 객체는 프로그램에서 여전히 해당 객체를 사용하고 있다는 것을 의미한다. 사용되지 않는 객체 또는 참조되지 않는 객체는 더 이상 프로그램에서 해당 객체를 사용하고 있지 않다는 것을 의미이며, 참조되지 않는 객체가 사용하는 메모리를 다시 확보할 수 있다.
C와 같은 프로그래밍 언어는 메모리 할당 및 해제를 명시적으로 메모리를 건드리고 참조할 수 있다. JAVA에서는 메모리 할당 및 해제를 GC (Garbage Collection)가 자동적으로 처리한다. JAVA에서는 GC(Garbage Collection) 알고리즘 통해 관리하기 때문에 개발자가 직업 메모리 해제를 할 필요가 없고 만들어서도 안된다. GC(Garbage Collection) 관련 메서드를 함부로 호출하면 시스템 성능에 매우 큰 영향을 준다.
GC(Garbage Collection)의 기본 프로세스는 아래와 같다.
1. Making
Marking은 GC(Garbage Collection)가 사용 중인 메모리와 사용하지 않는 메모리를 식별한다.
참조된 객체는 파란색, 참조되지 않는 객체는 주황색으로 표시하고 있다 모든 객체가 Marking 단계에서 스캔이 된다. 시스템의 모든 객체를 스캔하는 경우에는 매우 많은 시간이 소요된다.
2. Normal Deletion
참조되지 않는 객체를 제거하여 사용 가능한 빈 공간에 대한 포인터 객체를 반환한다. 빈 공간에 대한 포인터 객체를 가지고 있다는 게 특징이다.
메모리 Allocator는 반환된 블럭의 참조 위치로 새로운 객체가 할당될 수 있도록 한다. 이렇게 하면 메모리 전부를 탐색하면서 비어있는 공간을 찾을 필요 없이 메모리 Allocator가 잡고 있는 영역에서 쉽고 빠르게 메모리 할당이 된다. 하지만 객체마다 할당되는 메모리 크기가 다르기 때문에 비어있는 공간에 딱 맞는 객체가 할당되기는 쉽지 않다. 남은 공간이 작으면 메모리를 할당할 수 없고, 크다면 공간이 남아 비효율적인 상황이 발생되는 단점이 있다.
3. Deletion with Compacting
Making에서의 단점을 보완하고 성능을 더욱 향상하기 위해 참조되지 않는 객체를 삭제하는 것 외에도 나머지 참조된 객체를 압축한다. 이런 작업은 새로운 메모리 할당을 훨씬 더 쉽고 빠르게 한다.
할당되어 있는 객체들을 맨 앞에서부터 차례대로 재배치하여 빈 공간을 확보함으로써 성능을 높인다.
앞에서 설명한 것처럼 JVM에서 모든 객체를 표시하고, 압축하여 재배치하는 것은 비효율 적일 수 있다. 점점 더 많은 객체가 할당될수록 객체의 목록이 증가하여 GC(Garbage Collection) 시간이 더 길어지게 된다. 하지만, 통계에 따르면 대부분의 객체는 짧은 수명을 가진다.
GC(Garbage Collection)가 발생하면 이벤트가 발생하는데, Sun에서는 이 이벤트를 Stop-the-world라고 표현한다.
GC(Garbage Collection)가 수행될 때 일시적 애플리케이션 수행이 정지된다. GC(Garbage Collection)를 수행하기 위해 JVM이 애플리케이션 실행을 멈추는 것이다. Stop-the-world가 발생하면 GC(Garbage Collection)를 실행하는 스레드를 제외한 나머지 스레드들은 작업을 멈춘다. 대부분의 GC(Garbage Collection) 튜닝은 Stop-the-world 시간을 최소화하는 것이다.
JVM Generations
GC(Garbage Collection)는 두 가지 전제 조건하에 만들어졌다.
- 대부분의 객체는 금방 접근 불가능한 상태가 된다.
- 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.
이러한 전제 조건으로 JVM의 성능을 향상하기 위해서 HotSpot VM에서는 크게 3개의 물리적 공간을 Young, Old, Permanent 세 영역으로 구분한다.
1. Young 영역
새롭게 할당된 객체의 대부분이 Young 영역에 할당된다. 대부분의 객체들은 금방 접근 불가능한 상태가 되기 때문에 매우 많은 객체가 Young 영역에 할당되었다가 사라진다. 살아남은 객체가 있다면 Old 영역으로 이동시킨다. 여기서 발생하는 GC(Garbage Collection)를 Minor GC라고 부른다.
2. Old 영역
Young 영역에서 살아남은 객체들이 여기로 복사된다. Young 영역보다 크기가 크게 할당되며, 할당된 크기가 큰 만큼 Young 영역보다 GC(Garbage Collection)가 적게 발생한다. 여기서 발생하는 GC(Garbage Collection)를 Major GC라고 부른다. Major GC는 Minor GC보다 느리기 때문에 이 영역을 최소화하는 것이 좋다.
3. Permanent 영역
Method Area라고 불리는 영역이며, JVM이 실행되기 위해 필요한 클래스와 메서드에 대한 메타데이터를 포함하고 있다. 이전에는 이곳까지 GC를 해야 하는 경우는 메모리 누수가 심각하게 발생한 경우라고 생각했다. 하지만 JDK7부터 Permanent 영역을 제거하려는 움직임이 있었고 결과적으로 JDK 8부터는 이 영역이 사라져 Heap영역에서 사용할 수 있는 메모리가 늘어났다. 또한 Permanent 영역을 스캔하기 위해 소모되었던 시간이 감소되어 GC(Garbage Collection) 성능이 향상되었다.
The Generational Garbage Collection Process
HotSpot VM에서 Heap 영역을 분리를 이해했으므로, 이 공간이 얼마나 어떻게 상호작용을 하는지 살펴보자.
1. 첫 번째로 새로운 객체가 생성되면 Eden 영역에 할당된다.
2. Eden 영역이 가득 차면, Minor GC가 발생한다.
3. 살아남은 객체들을 첫 번째 S0 survivor 영역으로 이동되고, 참조되지 않은 객체는 Eden 영역이 지워질 때 삭제된다. survivor 영역 사이에 우선순위가 있는 것은 아니다. 이 두 영역 중 한 영역은 반드시 비어 있어야 한다.
4. 또다시 Minor GC가 발생되면 Eden 영역에서 같은 일이 일어나는데 S0 survivor 영역에서 살아남은 객체는 Aging(Age 증가)되어 S1 survivor 영역으로 이동한다. 그 후 Eden 영역과 S0 survivor 영역은 clean 된다.
5. 또다시 Minor GC가 발생되면 위와 같은 프로세스가 반복된다 단지 survivor 영역이 교체된다. S0 - S1 영역을 서로 교체하면서 살아남은 객체를 Aging(Age 증가) 한다.
6. 계속해서 Minor GC가 발생되면서 일정한 Age threshold 값을 넘게 되면 Old 영역으로 할당된다. 아래 그림은 8번의 Minor GC가 일어난 상황에서 Old 영역으로 할당된 예시이다. (Tenued = Old Generation)
7. 위 과정을 계속 반복하면서 Old 영역에 객체가 쌓이게 되면 어느 순간 Major GC가 발생하게 된다.
8. 아래 그림은 GC(Garbage Collection) 프로세스의 전 과정을 보여주고 있다.
요약하자면, Making, Deleting, Compacting 3가지 큰 과정이 있으며, 좀 더 효율적으로 하기 위해 Heap 영역을 Young, Old, Permanent로 나누었다. 여기서 기억해야 할 부분은 GC(Garbage Collection)가 수행될 때 일시적 애플리케이션 수행이 정지되며, Stop-the-world 시간을 줄이는 게 핵심이다. 또한 Minor GC가 발생하면서 살아남은 객체에 Aging 되면서 일정 Age threshold 값을 넘게 되면 Old 영역으로 할당되는 부분을 기억하자.
'엔지니어링 > 성능과 튜닝' 카테고리의 다른 글
[성능과 튜닝] JAVA 메모리 관리 GC 방식 (0) | 2019.06.04 |
---|---|
[성능과 튜닝] JAVA 메모리 관리 (스택&힙) (0) | 2019.05.31 |
[성능과 튜닝] JMH 설치 및 설정 방법 (0) | 2019.03.03 |
[성능과 튜닝] 프로그램 성능 분석 (0) | 2019.02.22 |
- Linux 명령어
- effective java
- Eclipse
- Collection
- 개발환경
- 리액트 16
- 프로그래머스
- 경력관리
- 오라클
- 소프트웨어공학
- 자바
- Tomcat
- SQL
- javascript
- 오라클 내장 함수
- 제주도 여행
- 회고
- 자바스크립트
- Java
- 성능분석
- 제주도 3박4일 일정
- React
- sort algorithm
- 프로그래머
- 정렬 알고리즘
- 리액트
- Maven
- 이직
- 리눅스 명령어
- spring
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |