Android 공부

24. 가비지 컬렉션 ( Garbage Collection)

young313 2023. 2. 10. 17:41

Garbage Collection (이하 GC) 는 메모리 관리 기법 중 하나로 프로그램이 동적으로 할당했던 메모리 영역 중 필요없게 된 부분을 해제하는 기능이다. 운영체제 공부를 하던 중에 , JVM 기반의 java, kotlin이 JVM 내의 GC를 이용해서 불필요한 메모리를 정리한다는 것을 알게 되어 간단하게 정리하려한다. 

 

프로그램을 실행하다가 메모리가 부족해지는 순간이 오면, 추가적으로 메모리를 요청하게 된다. 이때 GC가 실행되는 것이다. GC를 지원하지 않으면 메모리를 할당한 후 프로그래머가 해제까지 직접 해주어야 한다. C언어에는 이를 위한 메서드가 따로 있기도 하다. 따로 해제가 필요한 언어들은 메모리 할당을 해제하지 않으면 메모리 누수가 생기거나 메모리를 다시 사용하는 등의 버그가 발생하기도 한다. 

 

 

GC는 크게 두 가지 동작 방식으로 설명할 수 있다. 

 

1. Stop The World

이름에서 알 수 있듯 무언가는 멈추는 것이다. GC가 수행될 때 전체 어플리케이션이 멈추는 단계에 해당한다. 수행하고 있는 스레드 외에 모든 스레드가 작업을 멈추고 GC후에 작업을 재개한다. 이렇게 스레드를 모두 멈추는 이유는 간단하다. 가비지 처리된 메모리를 다시 사용할 수 있도록 모으는 과정인데 이때 다른 스레드가 메모리를 사용하면 꼬일 수 있기 때문에 다른 스레드를 모두 멈춘다고 한다. 

 

 

2. Mark and Sweep 

Mark 는 GC의 대상을 판별한다. Sweep 은 Mark 된 메모리를 해제하는 단계라고 보면 된다. 

 

코틀린의 경우 GC가 메모리를 정리해주지만 그것 만을 믿고 효율적으로 코드를 작성하지 않으면 속도가 느려지고 성능이 저하될 수도 있다. "더 이상 사용하지 않는 객체에 대한 참조는 유지하면 안된다." 라는 말을 기억해야 한다. 

 

더보기

💡참조?

java 에는 primitive type, reference type 이 존재한다. 

기본타입은 stack에 직접 값을 가지고 있고 참조타입은 heap 영역의 객체 주소를 stack 영역에 가지고 있다. 주소값을 가지게 되는 것이 참조, 이때 가지고 있는 변수가 참조변수, 주소값이 참조값이다.

 

코틀린에서 사용하는 companion object 는 어플이 실행되는 동안 GC의 대상이 되지 않는다. 그래서 무거운 객체를 참조하고 있으면 심한 메모리 누수가 발생할 수 있다. 

 

 

또 더이상 필요하지 않은 객체에 null 을 할당함으로써 GC의 대상으로 만드는 방법도 있다. 할당된 메모리를 해제하는 명시적 함수가 없기 때문에 null 을 선언하는 것이 하나의 방법이다. 

 


사실 JVM 기반의 java, kotlin 에서 개발자가 GC에 신경쓰는 일은 쉽지 않다. 특히 나는 이러한 관리 방법이 완전히 와닿지는 않는다. 하지만 이런 개념이 존재하고, 메모리 누수에 신경써야 한다는 것은 기억할 필요가 있을 것이다.