* Garbage collection 을 이해하기 위해 학습한 내용을 정리 하였습니다.
내용 순서
1. GC란?
2. GC를 동작 하게 하는 JVM 이란?
3. GC의 동작 순서 (Mark-and-Sweep)
4. GC 는 언제 일어날까?
1. GC (Garbage Collection) 란?
JVM의 Heap 영역에서 사용하지 않는 객체를 삭제하는 프로세스를 말합니다.
가비지 컬렉션은 기본적으로 메모리 누수를 제거 하는것을 목적으로 두고 있습니다. Unreachable-but-not-deleted Object in memory.
2. GC를 동작 하게 하는 JVM 이란?
- 자바 가상 머신으로 자바 바이트 코드(.class 파일)을 OS 에 특화된 코드로 변환(인터프리터와 JIT컴파일러) 하여 실행합니다.
- 바이트 코드를 어떻게 실행 할수 있는지에 대한 스펙을 말합니다. 바이트 코드를 실행하는 표준(JVM 자체는 표준)이자 구현체(특정 밴더(오라클, 아마존,Azul.. 가 구현한 JVM) 라고 할수 있습니다.
- 특정 플랫폼에 종속적
- JVM은 본래 홀로 실행되지 않았습니다. 자바를 실행 시키는 최소한의 배포단위는 JRE(Java Runtime Enviroment : 자바 애플리케이션을 실행 할수 있도록 구성된 배포판, JVM 과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있습니다. 개발 관련 도구 미포함(JDK 제공)) 입니다.
- 운영체제의 메모리 영역에 접근하여 메모리를 관리하고 Garbage Collector 를 수행합니다.
기타
- Wirte One Run AnyWay
- Library : jar 파일등
- JDK : (Java Development Kit) : JRE + 개발에 필요한 툴, JAVA 11이후에는 JDK만 제공되어 JRE를 따로 제공하지 않습니다.
GC 가 Heap 영역에서 사용하지 않는 객체를 삭제하는 프로세스라고 말했는데 JAVA 의 메모리 영역에는 위와 같이 5가지의 영역으로 이루어져 있습니다. 힙 영역에는 객체를 저장는 공유 자원이 들어가는데 Object 타입의 데이터들 String 이나, List 등이 들어간다고 확인할 수 있습니다.
* Stack : 정적으로 할당된 메모리 영역 , 원시 타입의 데이터 값, Heap 영역에 생성된 Object 타입의 데이터의 참조값 할당
* Heap : 동적으로 할당된 메모리 영역, 모든 Object 타입의 데이터가 할당, Heap 영역의 Object 를 가리키는 참조 변수가 Stack 에 할당됩니다.
GC는 바로 JVM의 동적으로 할당된 메모리의 힙 영역에서 오브젝트 타입과 같은 객체를 판별하여 사용유무를 판별하고 삭제를 진행합니다.
그렇다면 GC 는 어떻게 판별 할것인지?
3. GC의 동작 순서 (Mark-and-Sweep)
GC는 Object 가 더이상 사용중인지 아닌지를 판별 하기 위해 위에 보이는 객체 트리에서 Mark-and-Sweep 이라는 알고리즘을 사용합니다. 이 알고리즘은 두가지 단계를 간단히 실행합니다.
1. 알고리즘은 GC 루트에서 시작하여 모든 개체 참조를 순회하고 발견된 모든 Object 를 살아있는 것으로 표시(Mark)합니다. Reachable Object 가 참조하고 있는 객체도 찾아서 마킹 됩니다. -> Mark
2. 표시된 개체가 차지하지 않은 모든 힙 메모리가 회수됩니다. -> Sweep
모든 객체 트리는 하나 이상의 루트 객체(Garbage-Collection Root)가 존재해야 합니다. 루트 객체가 될수 있는 4가지 종류는 아래와 같습니다.
1. Local variables
2. Active Java Thread
3. Static variable
4. JNI References
* JNI(Java Native Interface)
- 자바 애플리케이션에서 C, C++ , 어셈블리로 작성된 함수를 사용할 수 있는 방법을 제공
- Native 키워드를 사용한 메소드 호출 (C, C++ 로 작성된 라이브러리를 네이티브 메소드 라이브러리라고 한다)
- Thread 클래스의 currentThread 함수에서 확인해 볼수 있다.
4. GC 는 언제 일어날까?
GC는 힙에서 발생하는 프로세스 이기 때문에 Heap의 구조를 이해할 필요가 있습니다.
Heap 은 간단하게 New Generation 과 Old Generation 으로 구분할 수 있습니다.
그리고 GC가 발생하는 상세한 과정은 아래와 같습니다.
- Eden : 새로운 객체 할당이 되면 들어갈 수 있는 메모리 영역입니다.
- Eden 영역이 다 사용 될때 Garbage Collection이 발생합니다. 이때 발생하는 것을 Minor GC 라고 부릅니다.
- Eden 영역의 Reachable (mark 된) 객체는 Survival1 로 옮겨집니다. Eden 영역의 Unreachable(mark가 안된) 객체는 메모리에서 해제됩니다. (기본적으로 Eden 영역의 Reachable 객체는 Survival 1 으로 옮겨집니다. Eden 영역의 Unreachable 객체는 메모리에서 해제됩니다)
- Survival 1 영역으로 객체가 옮겨지고 Survival의 메모리 또한 다 채워지면 Survival1의 객체는 Suvival2 영역으로 이동하게 됩니다. 이때 이동한 객체는 Age 값을 증가받게 됩니다.
- Servival 2 이 다 찼을때는 Mark and Sweep 이 다시 발생하고 Servival 1 으로 이동, 이동 한 객체는 Age 값을 증가 합니다. 이 과정을 계속 반복한다.
- 결론적으로 Survival 1, 2 둘중 하나는 항상 비워진 상태를 유지하게 됩니다.
< 다시 정리>
- 다시 새로운 객체는 Eden 영역에 할당. Eden 영역이 모두 차면 Minor Gc 발생 Survival 한쪽 영역이 차면 다른 영역으로 Mark and Sweep 이 발생하면서 이동한 객체는 Age 값을 증가시킨다. 그리고 Age 값이 특정 값 이상이 되면 Old Genaration 영역으로 옮겨지는데 이 과정을 Promotion 이라고 합니다.
- Promotion 이 계속 발생하게 되면 Old Generation 이 다 차게 되는데 Old Generation 영역이 가득 차면 GC 를 실행하게 되고 이때 발생하게 된 GC 를 Major GC 라고 합니다.
이러한 과정이 반복 되면서 Garbage Collector가 메모리를 관리하게됩니다.
*. Garbage Collector 종류
- Serial GC
GC 를 처리하는 스레드가 1개이다. CPU 코어가 1개 있을때 사용하는 방식, 시간이 오래 걸린다.
Mark - compact collection 알고리즘 사용
- Paraller GC
GC 를 처리하는 스레드가 여러개 이다. Serial GC 보다 빠르게 객체를 처리할수 있다. Paraller GC 는 메모리가 충분하고 코어의 개수가 많을때 사용하면 좋다.
- Concurrent Mark Sweep GC
Stop-The-Word
GC 를 실행하기 위해 JVM 이 애플리케이션 실행을 멈추는 것이다.
stop-the-word가 발생하면 GC를 실행하는 스레드를 제외한 나머지 스레드는 모두 멈춘다. GC 작업을 완료한 이후에 중단한 작업을 다시 시작한다. Concurrent Mark Sweep GC 는 Stop the word 의 문제점을 보완한 GC 이다.
- G1 GC
https://www.youtube.com/watch?v=vZRmCbl871I
https://www.dynatrace.com/resources/ebooks/javabook/how-garbage-collection-works/
https://javabom.tistory.com/7
https://www.youtube.com/watch?v=Fe3TVCEJhzo
infrean 백기선 강좌 - 자바를 조작 하는 방법
https://1-7171771.tistory.com/140
jar 파일은 java 아카이브 파일
'java' 카테고리의 다른 글
[JAVA] - 변수(Variable) (0) | 2021.08.14 |
---|---|
[JAVA] 객체 메모리 할당 - Stack, Heap, GC (1) | 2021.08.14 |
[자바 병렬 처리 - 포크/ 조인 프레임 워크] (0) | 2021.04.17 |
[JAVA]스트림(Stream) 에서 기본형(Primitive type)은 왜 취약할까? (0) | 2021.04.13 |
[JAVA 개념] 추상클래스와 인터페이스의 차이점 ( + 상속과 구현) (0) | 2021.04.11 |