안드로이드 시스템·Compose 용어 사전
생명주기process death · SavedStateHandle

프로세스 죽음

백그라운드 앱을 OS가 메모리 회수로 통째로 죽이는 것. ViewModel로는 못 막는다.

백그라운드에 있던 앱 프로세스를 OS가 메모리 회수를 위해 통째로 종료하는 것.

회전과 무엇이 다른가

  • 회전 — Activity 만 죽는다. ViewModel 은 산다

  • 프로세스 죽음 — 프로세스가 죽는다. ViewModel 도 메모리에 있었으니 함께 사라진다

  • 그런데 사용자 입장에선 "내 앱으로 돌아왔을 뿐" 이다

    • OS 는 마지막 화면을 다시 그려 줘야 한다
    • 프로세스를 새로 띄우고 Activity 를 재생성한다
    • ViewModel 은 비어 있고, 사용자는 "방금 보던 그 화면" 을 기대한다

SavedStateHandle이 간극을 메운다

@HiltViewModel
class SearchViewModel @Inject constructor(
    private val handle: SavedStateHandle
) : ViewModel() {
    val query: StateFlow<String> = handle.getStateFlow("query", "")
    fun onQueryChange(q: String) { handle["query"] = q }
}

프로세스가 죽기 직전 OS 가 작은 Bundle 을 디스크에 저장한다 SavedStateHandle 은 그 Bundle 에 묶여 복원 시 값을 들고 돌아온다

정리
  회전         → ViewModel
  프로세스 죽음 → SavedStateHandle
  큰 데이터     → 어느 쪽에도 담지 않고 DB 에서 다시 로드

Bundle 크기 제한

Bundle 은 Binder 트랜잭션으로 전달된다 → 버퍼가 약 1MB 넘으면 TransactionTooLargeException 으로 앱이 죽는다

  • 담아도 되는 것 — 검색어 · 선택된 탭 · 스크롤 위치 · 화면 인자 id 담으면 안 되는 것 목록 데이터 · 비트맵 · 큰 JSON

어떻게 재현하나

개발자 옵션 → "활동 유지 안 함" 을 켠다

  • 화면을 벗어나는 순간 Activity 가 파괴돼 복원 경로를 매번 탄다

또는 앱을 백그라운드로 보낸 뒤 adb shell am kill <package> (force-stop 이 아니다 — force-stop 은 상태 저장까지 지운다)

회전만 시켜 보고 "복원 잘 된다" 고 결론 내리는 것이 가장 흔한 검증 누락이다

면접 함정

  • "프로세스가 죽으면 앱을 처음부터 다시 시작한다" → OS는 마지막 화면부터 복원하려 한다. 그래서 상태 저장이 필요하다.
  • "onSaveInstanceState는 백그라운드로 갈 때만 불린다" → 구성 변경 때도 불린다. 두 경로가 같은 Bundle을 쓴다.

앱이 죽는 우선순위

OS 는 메모리가 부족하면 낮은 순위부터 죽인다

  • 포그라운드 프로세스 — 지금 보이는 화면 — 거의 안 죽는다
  • 가시 프로세스 — 일부 보임 (다이얼로그 뒤)
  • 서비스 프로세스 — 포그라운드 서비스
  • 백그라운드 프로세스 — 안 보이는 Activity — LRU 로 오래된 것부터 죽는다
  • 빈 프로세스 캐시만 — 가장 먼저 죽는다

"내 앱은 안 죽겠지" 는 저사양 기기·게임을 오가는 사용자 앞에서 틀린다

복원 흐름

사용자가 앱 아이콘/최근앱을 누른다

  • OS 가 프로세스를 새로 만든다
  • Application.onCreate
  • 마지막 Activity 를 저장된 Bundle 과 함께 재생성
  • onCreate(savedInstanceState != null)

앱 입장에서는 '콜드 스타트인데 savedInstanceState 가 있는' 상태다

무엇이 복원되고 무엇이 안 되나

자동 복원

  • View 의 id 가 있는 기본 상태 (EditText 텍스트 · 스크롤 위치)
  • rememberSaveable · SavedStateHandle
  • Navigation 백스택과 경로 인자

복원 안 됨

  • ViewModel 의 필드
  • 싱글턴에 담아 둔 메모리 캐시
  • 정적 변수 (전부 초기화된다)

"싱글턴에 로그인 정보를 들고 있다" 는 앱이 프로세스 죽음 후 로그아웃되는 원인이다

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 생명주기 — Activity·Fragment·생명주기 인지