왜 Android / Kotlin에서는 RAII가 불가능한가

C++의 RAII는 자원 관리 문제를 매우 강력하게 해결한다.
그렇다면 자연스럽게 이런 질문이 생긴다.

“왜 Kotlin이나 Android에서는 RAII를 쓰지 않는가?”

정확히 말하면,
Android / Kotlin에서는 RAII를 언어 차원에서 구현할 수 없다.


RAII의 전제 조건

RAII가 성립하려면 다음 조건이 필요하다.

  1. 객체의 소멸 시점이 명확해야 한다.
  2. 소멸 시점이 스코프 종료와 일치해야 한다.
  3. 소멸자가 반드시 즉시 호출되어야 한다.

C++은 이 세 가지를 모두 만족한다.

  • 스택 객체는 스코프 종료 시 파괴된다.
  • 소멸자는 예외 여부와 관계없이 호출된다.
  • 객체의 생명주기는 언어 규칙으로 결정된다.

Kotlin / Java의 객체 생명주기

Kotlin과 Java는 GC 기반 언어다.

  • 객체는 힙에 할당된다.
  • 객체가 언제 소멸될지는 GC가 결정한다.
  • 스코프 종료와 객체 소멸은 무관하다.

다음 코드를 보자.

fun f() {
    val obj = Resource()
}

`

이 함수가 끝났다고 해서 Resource가 즉시 소멸된다는 보장은 없다.
객체는 “더 이상 참조되지 않을 뿐”이며,
실제 메모리 해제 시점은 알 수 없다.

이 한 가지 사실만으로 RAII의 전제 조건이 깨진다.


finalizer가 대안이 될 수 없는 이유

Java에는 finalize()가 있었고,
Kotlin에서도 동일한 개념을 사용할 수 있었다.

그러나 finalizer는 RAII의 대안이 되지 못한다.

  • 호출 시점이 비결정적이다.
  • 호출되지 않을 수도 있다.
  • 성능 비용이 크다.
  • Android에서는 사실상 사용 금지다.

그래서 modern JVM 생태계에서는
자원 관리를 finalizer에 의존하지 않는다.


try-finally와 use의 한계

Kotlin에는 다음과 같은 패턴이 있다.

lock.lock()
try {
    // 작업
} finally {
    lock.unlock()
}

또는

FileInputStream("a.txt").use {
    // 사용
}

이 방식은 안전하다.
하지만 이것은 RAII가 아니다.

이유는 명확하다.

  • 자원 해제는 객체의 소멸이 아니라
  • 언어 문법에 의해 수행된다

즉,

  • “이 객체가 살아 있는 동안 자원을 가진다”가 아니라
  • “이 블록이 끝나면 자원을 해제한다”이다.

RAII의 책임 주체는 타입이지만,
Kotlin 방식의 책임 주체는 코드 구조다.


Android 환경에서의 추가 제약

Android에서는 다음 제약이 더해진다.

  • GC 타이밍이 앱 성능에 직접 영향을 준다.
  • 메모리 압박이 잦다.
  • finalizer는 ANR과 직결될 수 있다.
  • 리소스 누수는 즉시 크래시로 이어질 수 있다.

그래서 Android에서는 다음이 강제된다.

  • 파일, 커서, 스트림은 명시적으로 닫는다.
  • lock은 반드시 try-finally로 해제한다.
  • lifecycle에 맞춘 명시적 정리가 필요하다.

RAII처럼 “언어가 알아서 정리해준다”는 접근은 허용되지 않는다.


그럼 Kotlin에서는 RAII가 완전히 불가능한가

완전히 불가능하지는 않다.
하지만 흉내만 낼 수 있을 뿐 동일하지는 않다.

  • use {}는 RAII의 일부 개념만 차용한다.
  • inline 함수와 람다를 이용해 스코프를 제한한다.
  • 그러나 객체 생명주기와는 여전히 분리되어 있다.

즉, Kotlin의 자원 관리는

  • RAII가 아니라
  • Scoped Resource Management에 가깝다.

정리

RAII가 가능한 이유는 C++이 특별해서가 아니다.
C++은 다음을 언어 차원에서 보장하기 때문이다.

  • 결정적 소멸
  • 스코프 기반 객체 생명주기
  • 예외와 무관한 소멸자 호출

Kotlin / Android는 GC 기반 언어이며,
객체 소멸 시점이 언어 규칙에 포함되어 있지 않다.

따라서 Android에서의 자원 관리는
RAII가 아니라 명시적 구조와 규칙에 의존한다.

Leave a Comment