본문 바로가기
Tech-Java

Garbage Collection

by redcrow 2016. 3. 17.

"자바 성능 튜닝이야기(2013, 인사이트)" 중 GC 부분 정리


1. Hot Spot

- Java 성능을 개선하기 위해 Sun이 개발한 JIT(Just In Time) 컴파일러

- JDK 1.3 부터 기본 VM으로 사용

- HotSpot VM의 주요 컴포넌트

1) VM Runtime

2) JIT 컴파일러

3) 메모리관리자




[출처 : Java Garbage Collection Basics - http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html ]


- Class Loader Subsystem : 클래스나 인터페이스를 JVM으로 로딩

- Execution Engine : 로딩된 클래스의 메서드에 포함 되어있는 인스트럭션 정보를 실행




2. Java의 메모리영역




[출처 : https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/ ]


1) Heap Memory : GC가 담당하는 영역

클래스 인스턴스, 배열등이 이 메모리에 적재된다. Shared Memory라고도 불리우며 여러 Thread에서 공유하는 데이터들이 저장된다


2) Non-heap Memory : 자바의 내부 처리를 위해서 필요한 영역이며 주로 Method 영역

(1) Method 영역 : 모든 JVM 스레드에서 공유

- 런타임 상수 풀

- Method 데이터, Method , 생성자코드

(2) JVM 스택

스레드가 시작될때 JVM 스택이 생성되며 이 스택에는 메서드가 호출되는 정보인 프레임(frame)이 저장된다. 그리고 지역변수와 임시결과, 메서드 수행과 리턴에 관련된 정보들도 포함

(3) 네이티브 메서드 스택

자바코드가 아닌 다른 언어로 된 (보통은C) 코드들이 실행하게 될 때의 스택정보를 관리

(4) PC레지스터

자바의 스레드들은 각자의 PC(Program Counter) 레지스터를 갖는다. 네이티브한 코드들 제외한 모든 자바 코드들이 수행될때 JVM의 인스트럭션 주소를 PC레지스터에 보관한다


[참고]

스택의 크기는 고정하거나 가변적일수 있다. 연산을 하다가 JVM의 스택크기의 최대치를 넘을 경우 StackOverflowError가 발생한다. 가변적일 경우 스택의 크기를 늘리려고 할때 메모리가 부족하거나 스레드를 생성할때 메모리가 부족할 경우 OutOfMemoryError가 발생한다.


3. Garbage Collection

1) GC의 역할

- 메모리 할당

- 사용중인 메모리 인식

- 사용하지 않는 메모리 인식



[출처 : Java Garbage Collection Basics - http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html ]


=> Perm(Permanent)영역은 자바언어 레벨에서 사용되는 영역이 아니므로 논외 (Java 8부터 미사용)

   Virtual 영역도 가상영역이므로 제외. 따라서 우리가 고려해야할 자바의 메모리 영역은 Young(Eden, Survivor1, Survivor2), Old(Tenured)영역이다.  (Virtual 영역이 그림에서 안보이는데  Tenured 우측영역이다)

[참고]
String에 intern() 을 사용하면 문자열의 값을 == 로 비교할 수 있어 참조비교를 하는 eqauls보다 성능이 빨라지지지만 Perm 영역으로 들어가기 때문에 Perm영역의 GC가 발생한다.

2) 객체의 생성과 소멸
(1) 메모리에 객체가 생성되면 Eden 영역에 객체가 지정된다
(2) Eden영역이 꽉차면 객체는 Survivor영역으로 옮겨진다. Survivor1과 2는 구분을 위한것뿐이며 우선순위는 없다. 두개의 영역중 반드시 하나는 비어있어야 하며 비어있는 Survivor으로 Eden영역의 객체중 GC후 살아남은 객체들이 이동한다.
(3) 할당된 Survivor영역이 차면 GCr가 되면서 Eden영역에 있는 객체와 꽉 찬 Survivor영역에 있는 객체가 비어있는 Survivor영역으로 이동한다. 이러한 작업을 반복하면서 Survivor1 과 2를 왔다갔다 하던 객체들은 Old 영역으로 이동한다. Survivor 영역보다 큰 객체는 Young에서 바로 Old영역으로 이동한다.

3) GC의 종류
- 마이너 GC : Young 영역에서 발생하는 GC
- 메이저 GC : Old 영역이나 Perm영역에서 발생하는 GC - 비용소모가 더 심하다

4) GC의 방식
JDK 7 이상에서는 아래의 5가지 GC방식을 지원한다
- Serial Collector
- Parallel Comllector
- Parallel Compacting Collector
- Concurrent Mark-Sweep(CMS) Collector
- Garbage First Collector (G1 콜렉터)

5) 강제로 GC 시키기
System.gc()메서드나 Runtime.getRuntime().gc()를 사용하면 강제로 GC를 발생시킬수 있으나 GC실행자체가 application 성능에 영향을 미치므로 사용하지 않는다.


댓글