이번 포스팅에는 OOP(object-oriented programming)
즉, 객체 지향 프로그래밍의 객체라는 존재로 인하여 탄생한 "청소부" Garbage Collecter 에 대해 다뤄보겠다.
GC란?
Garbage Collecter
메모리 영역중 heap 영역에서 사용하지 않은 객체들을 제거해주는 청소부.
(힙 메모리 영역에서 사용되지 않는 객체를 지워주는 프로그램)
[자바와 코틀린의 객체 선언 방식]
JAVA : Person person = new Person(" ")
Kotlin : var person = Person(" ")
- 객체지향 언어들 중 자바는 위와 같이 new라는 키워드 등으로 생성한 객체를 다룬다.
자바 코드는 컴파일 후 메모리에 올라가게 되고 메모리의 여러 영역중에서도 Heap 영역에 할당된다.
(더 정확히는 person은 참조 변수로서 stack 영역에, 참조 변수로 연결된 실제 객체는 Heap 영역에 저장된다.)
아래 그림에서 자세히 설명할 예정! - 이런 과정으로 수많은 객체가 생성되고 메모리에 올라가기 때문에,
사용되지 않는 객체들은 메모리에서 지워주는 과정 또한 필요하다. - 이 역할을 해주는 친구가 바로 쓰레기 청소부 GC 이다.
메모리영역
GC의 동작방식을 알기 위해선 메모리 영역부터 알아야 한다.


- Code영역
- CPU는 코드 영역에 저장된 명령어를 하나씩 가져다 처리함.
(예를 들어, 카카오톡 PC 버전을 실행시키려면 C 드라이브같은 보조기억장치에 존재하는 카카오톡 파일들을 메모리에 올려야하며 이때 실행에 쓰이는 명령어들이 다음 Code 영역에 올라간다.)
- CPU는 코드 영역에 저장된 명령어를 하나씩 가져다 처리함.
- Data 영역
- 전역 변수, 정적 변수(static)가 저장되는 영역
⇒ 프로그램 시작부터 종료까지 메모리에 자리 차지하기때문에 막 선언하면 안됨.
⇒ 글로벌 변수같은것이 그 예가 될 수 있다.
- 전역 변수, 정적 변수(static)가 저장되는 영역
- heap 영역
- 런타임에 크기가 결정됨.
- 참조형 타입 객체, 배열 등이 저장.
- 사용자가 직접 관리할 수 있는 영역.
- 여러 스레드에서 공유하는 영역이기에 공유메모리 라고도 불림. (스레드는 아래 그림처럼 힙 영역을 공유함)
- 스레드마다 스택 영역이 각각 할당.
- 복잡한 타입의 변수들이 저장됨.
- 클래스, 인터페이스가 저장됨.
- ex) Person a = new Person() 에서
참조변수인 Person a는 스택에 쌓이이고,
new Person()은 객체기 때문에 힙에 쌓임.
- Stack 영역
- 컴파일 타임에 크기 결정.
- 함수의 호출과 관계되는 지역변수, 매개변수
- 리턴값등이 저장되는 영역.
- 함수의 호출과 함께 할당.
- 간단한 변수 + Heap을 가리키는 주소값을 담는 변수
- (LIFO) 나중에 들어온 녀석이 먼저 나가는 구조.
JVM GC의 동작 방식
GC는 Heap 영역에서 작동한다!!
위에서 말한 Heap은 다음과 같은 논리적인 구조로 구성되어 있다. (실제로 막 칸막이가 있고 그러지 않음..)

Heap은 young, old 영역으로 나뉨!
- Young 영역 : Eden + From + To
- Old 영역 : 하나의 모양으로 구성된듯.
또한 각 영역에 GC 를 이렇게 부른다.
- young 영역 작동 GC : Minor GC
- old 영역 작동 GC : Major GC
각각을 나눈 이유!
메모리 구조에서 Heap 영역은 객체가 들어오는 영역이며, 들어온 객체가 언제 나갈지 모르기 때문에
들어온지 별로 안된 Young 객체와 오래된 Old 객체를 구별하하여 객체 관리에 용이하도록
다음과 같은 논리 구조를 구성하였다.
Stop The World ?
가비지 컬렉터는 STW 라는 상황속에서 활동을 할 수 있다.
GC를 실행시키는 스레드를 제외하고 모든 스레드들이 멈추는 상황.
아래에서 설명하겠지만, GC 작업으로 인하여 힙 메모리상에 빈 공간이 발생되는데
효율적인 메모리 관리를 위해선 GC 작업 이후 빈 공간을 모두 메우는 작업 후에 새 객체를 받아야 한다.
또한 스레드가 멈추어야 현재 메모리 상에서 살아있는 객체를 정확히 식별해 치울 수 있다.
이러한 관리 문제로 인해 STW 를 발동 시킴.
그래서 힙 영역을 Young, Old 로 나누고 Minor GC가 어떻게 동작하는데?!
1. 새 객체는 Eden 영역에 할당된다.
2. Eden 영역이 꽉 차면 살아있는 객체를 확인한다.
3. 살아있는 객체를 To 영역으로 복사한다.
4. Eden 영역의 객체를 비우고 다시 새 객체를 Eden 영역으로 받는다.
5. Eden 영역이 꽉 차면 Eden 영역과 To영역에 살아있는 객체를 확인한다.
6. Eden 영역과 To 영역의 살아있는 객체를 From 영역으로 복사한다. (객체들의 위치 : From)
7. Eden, To 영역의 객체를 없애고 From 영역과 To영역의 이름을 바꾼다. (객체들의 위치 : To) + Life Count 가 1 증가
8. 또 다시 Eden 영역이 꽉 차게되면 Eden 영역과 To 영역의 살아있는 객체를 탐지한다.
9, 살아있는 객체 중 To에 있는 객체들의 Life Count가 Max라면 해당 객체를 Old 로 넘긴다.
10. Eden 영역과 To 영역의 살아있는 객체들을 From 영역으로 복사한다.
11. Eden과 To 영역을 없애고, From 영역과 To 영역의 이름을 바꾼 뒤 Life Count 1 증가
-반복-
여기서 말씀하신 내용을 가져왓씁니다..! https://s2choco.tistory.com/14
[Java] Garbage Collection 동작 방식
이번 포스팅에서는 JVM에서의 Garbage Collection 동작 방식에 대해 정리하려고 한다. 안드로이드 컴파일 과정을 공부하던 중에 Dalvik은 GC 방법으로 CMS 알고리즘을 사용하고, ART는 Customed CMS 알고리즘
s2choco.tistory.com
Dalvik 과 ART의 GC 방식 차이
위에서 Minor GC 방식에 대해 알아보았다.
그런데 Android는 현재 JVM => DVM(dalvik virtual Machine) => ART 로 변해왔다 하던데
가비지 컬렉팅의 차이가 좀 있으려나?
DVM
CMS 알고리즘 사용 (Concureent Mark Sweep)
- STW 현상을 줄이고자 나온 GC 알고리즘, 자주 참조되는 객체를 한번에 찾지 않고 4번에 걸쳐 찾는 방식을 사용.
- old 영역을 GC 하는 과정에서 Heap 메모리 단편화가 발생하고, 진행 불가정도로 단편화가 심한 경우에는 Compaction이라는 작업을 진행. => 이때 STW 상태가 오래 발생!
ART
CMS 를 개선한 Customed CMS 알고리즘 사용
- Compacting GC를 도입하여 메모리 단편화를 제거하고 메모리 공간 효율성 높이며 좀더 빠른 할당을 가능하게 함
- 앱이 백그라운드로 내려가면 ART Compacting 작업 진행.
다음과 같은 차이점이 있다고 한다.
막 자세히는 들여다보지 않았지만, ART로 갈수록 효율적인 알고리즘을 사용해 극복하는것을 알 수 있었다 :)
이상 포스팅을 마치겠습니닷..!
학부생 레벨에서 쓴 글로, 다소 부족한 부분이 있을 수 있으니 친절한 피드백을 매우 환영합니다.
'Android' 카테고리의 다른 글
| [Android] Fragment의 정의와 필요성, Lifecycle 및 이에 따른 대응. (0) | 2023.06.25 |
|---|---|
| [Android] Activity Lifecycle 과 화면회전 시 변화 (0) | 2023.06.22 |
| [Android] Activity 가 있는데 Fragment는 왜 써? (0) | 2023.06.05 |
| [Android] JVM, DVM, ART (2) | 2023.05.19 |
| [Android] JVM란 무엇일까? (0) | 2023.04.05 |
