Java GC란?

Reading time ~2 minutes

Java GC란 무엇이고, 어떻게 동작하는가?

그전에 용어 정리

HotSpot

HotSpot is a Java virtual machine for desktop and server computers, maintained and distributed by Oracle Corporation. It features improved performance via methods such as just-in-time compilation and adaptive optimization. - Wikipedia

가상 머신이란다.. JIT나 최적화 같은걸 써서 성능을 끌어올리는 JVM.

JIT 최적화

컴파일 언어라고 모든 소스코드를 컴파일하고 메모리에 올려서 동작하는 줄 알았더니 아니더라. 모든 코드는 우선 인터프리터에 의해서 시작되고 해당 코드가 많이 사용되면 그때 컴파일 대상으로 옮겨서 컴파일하고 사용한다.

  • invocation counter : 메소드를 시작할 때 증가
  • backedge counter : 높은 바이트 코드 인덱스 > 낮은 인덱스로 옮겨갈 때 증가

많이 많이 써서 컴파일 요청 > 컴파일 큐 쌓고 > 컴파일러 스레드가 대상 코드 골라서 > 컴파일 > 소스와 컴파일된 코드를 연결

! 이때 컴파일 중인 코드가 불리면?

인터프리터는 카운터값 초기화하고 그냥 하던데로 할 수도 있고! 이게 기본이고 컴파일 모두 끝날 때까지 기다렸다가 그 코드를 읽을 수 도 있고.

Young영역

자바에서 새로운 객체가 생성되면 이 영역으로 할당된다. Young영역은 또 3 구역으로 나뉜다. Eden, Survivor 2개. 맨 첨에는 Eden에 할당되고 이후 GC에서도 살아 남으면 Survivor로 옮겨진다.

Old영역

young영역에 있는 Survivor에서도! 살아남은 객체들이 Old에 머무른다.

Java GC 종류

jvm_heap

동작하는 곳을 기준으로 Minor GC, Major GC(Full GC)로 나뉜다.

Minor GC

Minor GC는 Young 영역에서 일어나는 GC를 말한다. Eden > Survivor 로 갈 때, 또 Survivor > Survivor로 옮기는 녀석이 Minor GC이다.

객체 생성되면 Eden으로 가고 여기 차면 GC 이 GC할때 사용중인 애들은 Survivor로 가는데 일을 하나 더 함 기존에 Survivor에서 살던 객체들도 GC를 벗어날 수 없는데 여기서 살아남은 애들도 다른 Survivor로 간다. 무조건 한 개는 비어있어야 하고 Eden + Survivor1 => Survivor2로 간다.

이걸 여러번 반복하면서 왔다갔다 하면 Old 영역으로 이동한다.

Major GC

Major GCFull GC라고도 하고 Old 영역에서 일어나는 GC를 일컫는다. 지만! Permanent 영역에서 일어나는 GC도 major GC에 포함되지만 최신 자바에선 빠질 예정이므로. Old만 생각한다.

얘는 Young처럼 몇 구역으로 나뉜게 아니라 그냥 한덩어리인데 어떤 애들이 들어오냐면 Survivor에서 끈질기게 살아남은 녀석들과 객체가 생성될 때 너무나 커서 Eden에서 수용할 수 없는 애들이 들어온다.

얘네들을 GC할 땐 우선 Survivor를 참조하고 있는지 확인한다. 이과정에서 Card table이란걸 사용하고, 모든 객체를 둘러보지 않는다. 그럼 card table만 보고 연결된 객체인지 판별한다음 GC 대상이 된다.

Java GC 방식

Serial GC

minor, major GC를 순차적으로 실행한다. 하나의 CPU를 사용하는데에서 이 방식을 택하고 GC가 돌면 두 종류의 GC 모두 수행하고, 앱 실행은 잠시 멈춘다. 위험하다. 아 그리고 마지막 Old 영역을 컴팩션(한 쪽으로 몰아두는거)한다.

Parallel GC

병렬로 수행하는 애. 이걸로 CPU 노는 시간을 좀 줄일 수 있다. 병렬로 쫘라락 하기 때문에 부하를 줄이고 대기시간 감소시킬 수 있다.

Parallel Compacting GC

Parallel GC랑 비슷한데 Old 영역의 GC에서 차이가 좀 있다. 사용 안하는 객체 표시하고 나서 스윕(시리얼, 병렬에서 사용하는) 말고 종합 단계를 거친다.

  • 스윕단계 : 단일 스레드로 old영역을 쓸어버린다.
  • 종합단계 : 다중 스레드로 old영역을 분리해서 쓸어버린다.

Concurrent Mark-Sweep (CMS) GC

힙 메모리를 크게 잡았을 때 유용하고 단계가 다르다.

  • 초기 쓰레기 표시 > 앱 수행하면서 동시에 GC당할 애들 표시 > 그 중간에 또 생겼을지 모르니 다시 표시 > 쓸어버리는 단계 그리고 컴팩션을 안하니까 한 쪽으로 몰리지 않음

Garage First

g1

young 영역과 old 영역으로 안나뉘고 위 그림과 같이 나뉜다. 저렇게 쪼개서 각각 영역을 분배해 주고 GC할 때 마다 구역을 옮기겨준다.

Java GC 모니터링 도구

자바의 신께서 적으신 블로그. 나중에 찾아가기 쉽게 링크!

jstat, jstatd

HotSpot VM에 들어있는 GC모니터링 도구 jstat은 로컬 시스템에서 볼 수 있는 거고 jstatd는 원격으로 모니터링할 때 사용한다.

Visual GC

Visual GC는 오라클 jdk에서 제공하는 GUI 툴!

JPS

Jps는 자바에서 제공하는 jvm 프로세스 보여주는 도구이다. 유닉스 ps같은 건데 얘는 jvm이 띄운 프로세스 정보들을 보여준다.


출처

jvm heap : http://www.engineersbloc.com/collection/278/

garage first : http://www.herongyang.com/JVM/Memory-Serial-Parallel-Concurrent-Reginalized-Collectors.html

Dooray!

Dooray CalDav, IMAP 사용법 Continue reading

Vue.js

Published on February 10, 2018

Java_tuning5

Published on March 06, 2017