ckgod.github Help

Q32) Android의 프로세스

Android 애플리케이션에서 프로세스란 무엇이며, Android 운영체제는 이를 어떻게 관리하는가?

Android에서 프로세스는 애플리케이션 구성요소가 실행되는 실행 환경을 나타냅니다. 각 Android 앱은 다른 앱과 격리된 자체 프로세스에서 단일 실행 스레드로 작동하여 시스템 보안, 메모리 관리 및 오류 허용을 보장합니다. Android 프로세스는 Linux 커널을 사용하여 운영체제에 의해 관리되며 엄격한 라이프사이클 규칙을 따릅니다. 기본적으로 동일한 애플리케이션의 모든 구성요소는 메인 스레드라고 불리는 동일한 프로세스와 스레드에서 실행됩니다.

Android에서 프로세스가 작동하는 방식

Android 애플리케이션이 실행될 때, 운영체제는 Linux의 fork() 시스템 호출을 사용하여 해당 애플리케이션을 위한 새 프로세스를 생성합니다. 각 프로세스는 Dalvik 또는 ART (Android Runtime) 가상 머신의 고유한 인스턴스에서 실행되어 안전하고 독립적인 실행을 보장합니다. Android는 각 프로세스에 고유한 Linux 사용자 ID (UID)를 할당하여 권한 제어 및 파일 시스템 격리를 포함한 엄격한 보안 경계를 적용합니다.

애플리케이션 구성요소와 프로세스 연결

기본적으로 Android 애플리케이션의 모든 구성요소는 동일한 프로세스 내에서 실행되며, 대부분의 애플리케이션은 이 표준을 따릅니다. 그러나 개발자는 AndroidManifest.xml 파일의 android:process 속성을 사용하여 프로세스 할당을 사용자 정의할 수 있습니다. 이 속성은 <activity>, <service>, <receiver>, <provider>와 같은 구성요소에 적용될 수 있으며, 구성요소가 별도의 프로세스에서 실행되거나 프로세스를 선택적으로 공유할 수 있도록 합니다. <application> 요소 또한 이 속성을 지원하며, 모든 구성요소에 대한 기본 프로세스를 정의합니다.

<service android:name=".MyService" android:process=":remote" />

이 예제에서 MyService 서비스는 :remote라는 별도의 프로세스에서 실행되어 독립적인 작동과 향상된 오류 허용을 가능하게 합니다. 또한, 다른 애플리케이션의 구성요소는 동일한 Linux 사용자 ID를 가지고 동일한 인증서로 서명된 경우 동일한 프로세스를 공유할 수 있습니다.

Android는 시스템 리소스 요구에 따라 프로세스를 동적으로 관리하며, 필요할 때 우선순위가 낮은 프로세스를 종료합니다. 더 이상 보이지 않는 Activity를 호스팅하는 프로세스는 보이는 구성요소를 호스팅하는 프로세스에 비해 종료될 가능성이 더 높습니다. Android 시스템은 연결된 구성요소가 작업을 수행해야 할 때 프로세스를 다시 시작하여 최적의 시스템 성능과 사용자 경험을 보장합니다.

프로세스와 앱 라이프사이클

Android는 시스템 메모리 및 앱의 현재 상태를 기반으로 프로세스와 앱 라이프사이클을 엄격한 우선순위 계층에 따라 관리합니다:

  1. 포그라운드 프로세스 (Foreground Process): 사용자와 활발하게 상호작용하며 실행 중인 프로세스입니다. 이는 가장 높은 우선순위를 가지며 거의 종료되지 않습니다.

  2. 가시 프로세스 (Visible Process): 사용자에게 보이지만, Dialog 뒤의 Activity처럼 활발하게 상호작용하지 않는 프로세스입니다.

  3. 서비스 프로세스 (Service Process): 데이터 동기화 또는 음악 재생과 같은 작업을 수행하는 백그라운드 서비스를 실행하는 프로세스입니다.

  4. 캐시된 프로세스 (Cached Process): 더 빠른 재실행을 위해 메모리에 유지되는 유휴 프로세스입니다. 캐시된 프로세스는 가장 낮은 우선순위를 가지며 메모리가 부족할 때 가장 먼저 종료됩니다.

Android 시스템은 메모리를 확보하고 시스템 안정성을 유지하기 위해 우선순위가 낮은 프로세스를 자동으로 종료합니다.

보안 및 권한

각 Android 프로세스는 Linux 보안 모델을 사용하여 샌드박스 처리되어, 엄격한 권한 기반 접근 제어를 적용합니다. 이 격리는 Android 권한 시스템을 통해 명시적으로 권한이 부여되지 않는 한 애플리케이션이 다른 프로세스의 데이터에 접근할 수 없도록 보장합니다. 이 보안 모델은 Android의 멀티태스킹 환경에 필수적이며, 시스템 안정성과 데이터 프라이버시를 모두 지원합니다.

요약

Android에서 프로세스는 애플리케이션 구성요소를 위한 실행 환경 역할을 하며, 격리되고 안전하며 효율적인 앱 작동을 보장합니다. Android 시스템에 의해 관리되는 프로세스는 메모리 제약, 사용자 활동 및 애플리케이션 우선순위에 따라 생성, 스케줄링 및 종료됩니다.

개발자는 매니페스트 파일의 구성과 Android의 권한 관리 시스템을 통해 프로세스 동작을 추가로 제어하여 강력하고 확장 가능한 애플리케이션 개발을 가능하게 합니다.

Q) 서로 다른 Android 구성요소가 별도의 프로세스에서 실행되어야 하는 애플리케이션을 개발하고 있습니다. AndroidManifest에서 이를 어떻게 구성하며, 여러 프로세스를 사용하는 데 따르는 잠재적인 단점은 무엇입니까?

각 구성요소(`Activity`, `Service`, `Receiver`, `Provider`) 태그 내에 `android:process` 속성을 추가하여 지정합니다. 프로세스 이름을 지정하는 방식에는 두 가지가 있으며, 이에 따라 프로세스의 성격이 달라집니다.

A. 전용 프로세스 (Private Process)

프로세스 이름이 콜론(: )으로 시작합니다. 이 프로세스는 해당 앱 전용이며, 다른 앱과 공유되지 않습니다.

<manifest> <application> <activity android:name=".MainActivity" /> <service android:name=".MusicService" android:process=":music_player" /> </application> </manifest>

B. 전역 프로세스 (Global Process)

프로세스 이름이 소문자로 시작하며, 완전한 패키지 명명 규칙(예: com.example.music.service )을 따릅니다. 인증서와 사용자 ID가 같다면 다른 애플리케이션의 컴포넌트도 이 프로세스에서 실행될 수 있어 리소스를 공유할 수 있습니다.

<service android:name=".SharedService" android:process="com.example.myapp.service" />

잠재적 단점

각 프로세스는 완전히 독립된 ART 가상 머신(VM)인스턴스를 가집니다.

  1. 메모리 사용량 급증: 프로세스마다 새로운 VM 인스턴스가 생성되므로, 공통 라이브러리와 리소스가 중복으로 로드됩니다.

  2. 데이터 공유 및 동기화의 어려움: 프로세스 간에는 메모리 공유가 불가능합니다.

    • Static 변수 초기화: Process A 에서 GlobalObject.count = 10 으로 설정해도, Process B 에서의 GlobalObject.count는 여전히 초기값(0)입니다.

    • 싱글톤 불일치: 각 프로세스마다 별도의 싱글톤 인스턴스가 생성되므로, 앱 전체에서 유일한 인스턴스를 보장할 수 없습니다.

    • 동기화 문제: SharedPreferences는 멀티 프로세스 환경에서 동시 쓰기 시 데이터 유실 위험이 있어 MODE_MULTI_PROCESS는 더 이상 권장되지 않습니다.

  3. 통신 복잡도 증가(IPC 필수): 단순한 함수 호출이 불가능하며, 반드시 IPC를 거쳐야 합니다.

  4. Application 객체의 중복 실행: Application.onCreate()는 각 프로세스가 생성될 때마다 실행됩니다.

    • 만약 onCreate()에서 무거운 초기화 작업(예: Analytics SDK 초기화, DB 연결)을 수행한다면, 모든 프로세스에서 이 작업이 반복 실행되어 낭비가 발생합니다. 따라서 ProcessName을 체크하여 분기 처리를 해야합니다.

Q) Android는 메모리가 부족할 때 어떤 프로세스를 종료할지 결정하기 위해 우선순위 기반 프로세스 관리 시스템을 사용합니다. 시스템이 프로세스에 우선순위를 할당하는 방법과 중요한 프로세스가 종료되는 것을 방지하기 위해 개발자가 따라야 할 전략을 설명할 수 있습니까?

안드로이드는 현재 앱의 컴포넌트 상태와 사용자 인지 여부를 기준으로 프로세스를 4가지 주요 등급으로 분류합니다.

  1. 포그라운드 프로세스 (Foreground Process) - 가장 중요

    • 사용자가 현재 상호작용하고 있는 프로세스입니다.

  2. 가시적 프로세스 (Visible Process) - 중요

    • 사용자가 화면을 보고 있지만, 직접 터치 등의 상호작용은 하지 않는 상태입니다.

    • onPause() 상태의 Activity

    • 포그라운드 서비스를 바인딩하고 있는 경우

  3. 서비스 프로세스 (Service Process) - 보통

    • 화면에 보이지 않지만 백그라운드에서 작업을 수행 중인 상태입니다.

    • 음악 재생, 네트워크 다운로드 등이 여기에 속하지만, 포그라운드 서비스로 승격되지 않았다면 메모리 부족 시 종료 대상이 됩니다.

  4. 캐시된 프로세스 (Cached Process) - 종료 1순위

    • 현재 사용되지 않지만, 나중에 빠른 실행을 위해 메모리에 남겨둔 프로세스입니다.

    • onStop() 상태의 Activity를 가진 앱들

    • 시스템은 메모리가 필요할 때 이들을 가장 먼저, 가차 없이 종료합니다.

개발자는 프로세스가 캐시된 프로세스로 분류되는 것을 막거나, 종료되더라도 복구할 수 있도록 설계해야 합니다.

  1. 포그라운드 서비스 (Foreground Service) 사용

앱이 백그라운드에서도 중요한 작업을 수행해야 한다면(예: 음악 재생, 네비게이션, 파일 업로드), 포그라운드 서비스를 사용해야 합니다.

  • 상태 표시줄에 알림을 띄움으로써 시스템에게 사용자가 이 작업을 인지하고 있음을 알립니다.

  • 프로세스 우선순위가 서비스에서 포그라운드급으로 격상되어 메모리 정리 타겟에서 벗어납니다.

  1. WorkManager 사용

즉각적인 실행이 필요하지 않은 작업은 서비스를 계속 띄워놓는 대신 WorkManager를 사용해야 합니다.

  • 시스템이 리소스가 여유로울 때 작업을 스케줄링하며, 작업 실행 중에만 일시적으로 프로세스 우선순위를 높여줍니다.

  • 배터리와 메모리 효율이 좋고, 최신 안드로이드 정책에 부합합니다.

  1. START_STICKY 사용 (복구 전략)

서비스가 강제 종료되었을 때 다시 살아나야 한다면, onStartCommand()에서 START_STICKY를 반환합니다.

  • 시스템이 메모리를 확보한 후, 서비스를 다시 생성해 줍니다. (마지막 Intent는 전달되지 않을 수 있음)

  1. 프로세스 분리

android:process속성을 이용해 무거운 작업을 별도 프로세스로 분리합니다.

  • 서브 프로세스가 메모리를 많이 사용하여 종료되더라도, 메인 프로세스는 살아남아 사용자 경험을 유지할 수 있습니다.

26 January 2026