자바 GC 정리

jy.YOON·2022년 9월 19일
0

자바

목록 보기
6/8

1.Heap 메모리

클래스 인스턴스, 배열이 이 메모리에 쌓임

공유 메모리 라고도 불리며, 여러 스레드에서 공유하는 데이터들이 저장되는 메모리

2.Non-Heap 메모리

자바의 내부처리를 위해 필요한 영역, 주된 영역역은 메서드 영역

2-1. 메서드 영역

메서드 영역은 모든 JVM 스레드에서 공유

ex)

런타임 상수 풀, 필드 정보(메서드 데이터, 메서드, 생성자 코드)

2-2. JVM 스택

스레드 시작시 JVM 스택이 생성된다.

이 스택에는 메서드가 호출되는 정보인 프레임 이 저장된다.

지역 변수, 임시 결과, 메서드 수행과 리턴 값 관련 정보들이 포함된다.

2-3. 네이티브 메서드 스택

자바 코드가 아닌 다른 언어로 된 코드들이 실행될때 스택 정보를 관리한다.

2-4. PC 레지스터

자바의 스레드들은 각자의 PC 레지스터를 갖는다.

네이티브 코드를 제외한 모든 자바 코드들이 수행될 때 JVM 인스턴트 주소를 PC 레지스터에 보관한다.

Heap 영역과 메서드 영역은 JVM 이 시작될 때 생성된다.

3.GC 원리

크게 보면 Young, Old(Tenured), Perm 3가지의 영역으로 나뉜다.

설명에선 Perm 영역은 자바 언어 레벨에서 사용하는 영역이 아니며, JDK 8 부턴 해당 영역이 사라지기 때문에 없는걸로 가정한다.

그림에서 Virtual 영역또한 고려하지 않는다.

그럼 4가지 영역 Young(Eden, Survivor1, Survivor2), Old(메모리 영역) 으로 나뉜다.

순서

  1. 메모리에 객체가 생성되면, 가장 왼쪽인 Eden영역에 객체가 생성된다.

  1. Eden 영역에 객체가 꽉차면 S1 또는 S2 영역으로 이동되며, 둘중 한 영역은 반드시 비어있어야 한다.

    비어 있는 영역에 Eden 영역에 있던 객체 중 GC 후에 살아 남은 객체들이 이동한다.

    (S1, S2에 우선순위가 있는것은 아니며 구분을 위해 1과 2로 나눈것)

  1. GC가 되면서 Eden 영역에 있는 객체와 꽉찬 Survivor 영역에 있는 객체가 비어있는 Survivor 영역으로 이동한다.

    이러한 작업을 반복하면서 S1<->S2 를 왔다갔다 하던 객체들은 Old 영역으로 이동한다.

Young 영역에서 Old 영역으로 넘어가는 객체 중 Survivor을 거치지 않고 바로 Old 영역으로 이동하는 객체가 있다.

그런경우 객체의 크기가 아주 큰경우이다.

ex)

Survivor 영역크기 16MB, 점유하는 객체크기 20MB 인경우

4.GC의 종류

GC는 크게 2가지 종류로 나뉜다.

  • 마이너 GC

Young 영역에서 발생하는 GC

  • 메이저 GC

Old 영역, Perm 영역에서 발생하는 GC

GC의 상호작용, 방식에 따라서 성능이 천차만별이다.

GC발생 또는 객체가 각 영역에서 다른 영역으로 이동시, 애플리케이션에 병목이 발생할 수 있으며, 성능에 영향을 준다.

그래서 핫 스팟 JVM에서는 스레드 로컬 할당 버퍼(TLABs: Thread Local Allocation Buffers)라는 것을 사용한다.

스레드별 메모리 버퍼를 사용한다면 다른 스레드에게 영향을 주지 않는다.

5가지의 GC 방식(JDK7 이상 버전)

1. Serial Collector

Young 영역과 Old 영역이 연속적(시리얼)으로 처리되며 하나의 CPU를 사용한다.

Sun에서는 이 처리를 수행할 때 Stop-the-world 라고 표현한다

시리얼 콜렉터가 수행될때 애플리케이션의 수행이 모두 정지된다.

img

순서
  1. 살아있는 객체들은 Eden 영역에 있다.
  1. Eden 영역이 가득차면 S1 영역으로 살아있는 객체가 이동한다.

    너무 큰 객체는 Old 영역으로 이동한다.

  1. S2 영역에 살아있는 객체는 S1 영역으로 이동한다.
  1. S1 영역이 가득 찬 경우, Eden 영역이나 S2 영역에 남아 있는 객체들은 Old 영역으로 이동한다.
  1. 이후 Old 영역이나 Perm 영역에 있는 객체들은 Mark-sweep-compact 콜렉션 알고리즘을 따른다

    간단하게, 쓰이지 않는 객체를 표시해서 삭제하고 한곳으로 모으는 알고리즘이다.

    Mark-sweep-compact 콜렉션 알고리즘 순서

    1.Old 영역으로 이동된 객체들 중 살아 있는 객체 식별(표시(Mark) 단계)

    2.Old 객체를 탐색하는 작업 수행, 쓰레기 객체 식별(스윕(Sweep) 단계)

    3.필요 없는 객체들을 지우고 살아있는 객체들을 한 곳으로 모은다.(컴펙션(Compact) 단계)

시리얼 콜렉터는 일반적으로 클라이언트 종류의 장비에서 많이 사용된다.

즉, 대기 시간이 많아도 크게 문제되지 않는 시스템에서 사용된다.

TMI) -XX:+UseSerialGC 로 옵션 사용

2. Parallel Collector

Throughput Collector 로도 알려진 방식이며, 해당 컬렉터의 목표는 다른 CPU가 대기 상태로 남아 있는 것을 최소화 하는 것이다.

Serial Collector 와 달리 Young 영역에서의 콜렉션을 병렬처리 한다.

많은 CPU를 사용하기 때문에 GC의 부하를 줄이고 애플리케이션의 처리량을 증가시킬 수 있다.

Old 영역의 GC는 Serial Collector와 마찬가지로 Mark-sweep-compact 콜렉션 알고리즘을 사용한다.

img

병렬 처리시 Stop the world 로 인해 발생하는 pause time 을 줄일 수 있다고 한다,

3. Parallel Compacting Collector

병렬 콜렉터와 다른점은 Old 영역에서 GC에서 새로운 알고리즘을 사용한다.

그러므로 Young 영역에 대한 GC는 Parallel Collector와 동일하며, Old 영역에서만 차별점이 있다.

Old 영역에서 발생되는 GC 3단계

표시 단계(Mark)

살아 있는 객체를 식별하여 표시해 놓는 단계

종합 단계(Summary)

이전에 GC를 실행하여 컴팩션된 영역에 살아 있는 객체의 위치를 조사하는 단계

컴팩션 단계(Compact)

컴팩션을 수행하는 단계, 수행 이후 컴팩션된 영역과 비어있는 영역으로 나뉨

Parallel Collector동일하게 이 방식도 여러 CPU를 사용하는 서버에 적합하다.

TMI) GC를 사용하는 스레드의 개수는 -XX:ParallelGCThreads=n 옵션으로 조정 가능하다.

-XX:+UseParallelOldGC 로 옵션 사용

[Parallel Collector 과 Parallel Compacting Collector 의 차이점]

2단계의 Sweep 단계와 Summary 단계의 차이

Sweep 단계는 단일 스레드가 Old 영역 전체를 탐색한다.

Summary 단계는 여러 스레드가 Old 영역을 분리하여 탐색하며, 앞서 진행된 GC에서 컴팩션된 영역을 별도로 탐색한다.

4. CMS(Concurrent Mark Sweep) Collector

Low Latency Collector 로도 알려져 있으며, 힙 메모리 영역의 크기가 클때 적합하다.

Young 영역에 대한 GC는 Parallel Collector 과 동일하다.

Old 영역에서 발생되는 GC 순서

초기 표시 단계

매우 짧은 대기 시간으로 살아 있는 객체를 탐색

컨커런트 표시 단계

서버 수행과 동시에 살아 있는 객체에 표시를 해 놓는 단계

재표시 단계

컨커런트 표시 단계에서 표시하는 동안 변경된 객체에 대해서 다시 표시하는 단계

컨커런트 스윕 단계

표시되어 있는 쓰레기를 정리하는 단계

CMS는 컴팩션 단계를 거치지 않기 때문에 왼쪽으로 메모리를 몰아 놓는 작업을 수행하지 않는다.

JavaGarbage5

CMS 콜렉터 방식은 2개 이상의 프로세서를 사용하는 서버에 적당하다.

가장 적당한 대상으론 웹 서버 가 있다.

TMI) -XX:+UseConcMarkSweepGC 로 옵션 사용

CMS 콜렉터는 추가적인 옵션으로 점진적 방식을 지원한다.

이 방식은 Young 영역의 GC를 더 잘게 쪼개어 서버의 대기 시간을 줄일 수 있다.

CPU가 많지 않고 시스템의 대기 시간이 짧아야 할 때 사용하면 좋다.

그러나 예기치 못한 성능 저하가 발생할 수 있으므로 충분한 테스트 후 적용이 필요하다.

5.G1(Garbage First) Collector

위의 설명한 가비지 컬렉터들은 Eden과 Survivor 영역으로 나뉘는 Young 영역과 Old 영역으로 구성되어 있다

그러나 G1은 지금까지의 가비지 컬렉터들과는 다른 영역으로 구성되어 있다.

G1 Garbage Collection (G1 GC)

바둑판의 사각형을 region 이라고 부른다.

Young 영역과 Old 영역이 물리적으로 나뉘어 있지 않고, 각 구역의 크기는 동일하다.

region 이 각각 Eden, Survivor, Old 영역의 역할을 변경해 가면서 하며, Humongous 라는 영역도 포함된다.

G1의 Young GC 과정

  1. 몇 개의 구역을 선정하여 Young 영역으로 지정한다.
  1. Linear(선형)하지 않는 구역에 객체가 생성되면서 데이터가 쌓인다.
  1. Young 영역으로 할당된 구역에 데이터가 꽉 차면 GC를 수행한다.
  1. GC를 수행하면서 살아있는 객체들만 Survivor 구역으로 이동시킨다.

살아 남은 객체들이 이동된 구역은 새로운 Survivor 영역이 된다.

그 다음 Young GC가 발생하면 Survivor 영역에 계속 쌓는다.

그러면서 몇번의 aging 작업(Survivor 영역의 객체가 몇번의 Young GC 후에도 살아있으면)을 거치면서 Old 영역으로 승격된다.

G1의 Old 영역 GC는 CMS GC의 방식과 비슷하며 6 단계로 나뉜다.

SWT라고 표시된 단계에서는 모두 Stop the world가 발생한다.

G1의 Old 영역의 GC 6단계

초기 표시(Initial Mark) 단계(SWT)

Old 영역에 있는 객체에서 Survivor 영역의 객체를 참조하고 있는 객체들을 표시한다

기본 구역 스캔(Root region scanning) 단계

Old 영역 참조를 위해 Survivor 영역을 탐색한다. 이 작업은 Young GC가 발생하기 전에 수행된다.

컨커런트 표시 단계

전체 힙 영역에 살이있는 객체를 탐색한다. 이때 Young GC 발생시 잠시 멈춘다.

재 표시(Remark) 단계(SWT)

힙에 살아있는 객체들의 표시 작업을 완료한다. 이때 SATB(Snapshot-at-the-beginning)라는 알고리즘을 사용하며, 이는 CMS GC 에서 사용하는 방식보다 빠르다.

청소(Cleaning)단계(STW)

살아있는 객체와 비어 있는 구역을 식별하고, 필요없는 개체들은 지운다. 그리고 나서 비어 있는 구역을 초기화 한다.

복사 단계(STW)

살아있는 객체들을 비어 있는 구역으로 모은다.

G1은 CMS GC의 단점을 보완하기 위해서 만들어 졌으며 GC 성능도 매우 빠르다.

하지만 GI이 빠르다고 무조건 이 콜렉터를 선택하는 것은 시스템의 장애로 연결되 있기 때문에 항상 안정화,성능테스트를 진행하고 도입하자.







출처

https://www.oracle.com/java/technologies/javase/javase-core-technologies-apis.html

https://d2.naver.com/helloworld/1329

http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788966260928

profile
5 Seconds rule

0개의 댓글

관련 채용 정보