프로세스 및 앱 수명 주기
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
대부분의 경우 모든 Android 애플리케이션은 자체 Linux 프로세스에서 실행됩니다.
이 프로세스는 일부 코드를 실행해야 할 때 애플리케이션용으로 생성되며 시스템이 다른 애플리케이션에 사용하기 위해 메모리를 회수해야 할 때까지 계속 실행됩니다.
Android의 특이하면서 기본적인 특징은 애플리케이션 프로세스의 수명 주기 전체 기간이 애플리케이션 자체에 의해 직접 제어되지 않는다는 점입니다.
대신 이 수명 주기 전체 기간은 시스템이 실행 중인 것으로 파악하는 애플리케이션 요소, 요소들이 사용자에게 중요한 정도 및 시스템에서 사용할 수 있는 전체 메모리 양을 조합하여 시스템에 의해 결정됩니다.
애플리케이션 개발자는 다양한 애플리케이션 구성요소(특히 Activity
, Service
, BroadcastReceiver
)가 애플리케이션 프로세스의 수명 주기에 영향을 미치는 방식을 이해하는 것이 중요합니다. 이러한 구성요소를 올바르게 사용하지 않으면 시스템이 중요한 작업을 하는 동안 애플리케이션 프로세스가 종료될 수 있습니다.
프로세스 수명 주기 버그의 일반적인 예는 BroadcastReceiver.onReceive()
메서드에서 Intent
를 수신한 후 스레드를 시작하고 함수에서 반환되는 BroadcastReceiver
입니다. 반환된 후에는 시스템에서 BroadcastReceiver
가 더 이상 활성 상태가 아닌 것으로 간주하므로 호스팅 프로세스가 더 이상 필요하지 않습니다(다른 애플리케이션 구성요소가 이 프로세스 내에서 활성 상태가 아닌 한).
따라서 시스템은 언제든지 프로세스를 종료하여 메모리를 회수할 수 있으며 이 과정에서 프로세스에서 생성되어 실행 중인 스레드를 종료합니다. 이 문제를 해결하는 방법은 일반적으로 BroadcastReceiver
에서 JobService
를 예약하는 것입니다. 그러면 시스템에서 프로세스에 진행 중인 활성 작업이 있다는 것을 알게 됩니다.
메모리가 부족할 때 종료해야 하는 프로세스를 결정하기 위해 Android는 프로세스 내에서 실행 중인 구성요소 및 구성요소의 상태에 따라 각 프로세스를 중요도 계층 구조에 배치합니다. 이러한 프로세스 유형은 중요도 순으로 다음과 같습니다.
- 포그라운드 프로세스는 사용자가 현재 하고 있는 작업에 필요한 프로세스입니다. 다양한 애플리케이션 구성요소로 인해 포함된 프로세스가 다양한 방식으로 포그라운드로 간주될 수 있습니다. 다음 조건 중 하나라도 충족되면 프로세스가 포그라운드에 있는 것으로 간주됩니다.
이러한 프로세스는 시스템에 몇 개밖에 없습니다. 메모리가 매우 부족하여 이러한 프로세스조차 계속 실행할 수 없을 때 최후의 수단으로만 종료됩니다. 일반적으로 이 경우 기기가 메모리 페이징 상태에 도달했으므로 사용자 인터페이스의 반응성을 유지하려면 이 작업(즉, 포그라운드 프로세스 종료)이 필요합니다.
- 가시적 프로세스는 사용자가 현재 알고 있는 작업을 하므로 이 프로세스를 종료하면 사용자 환경에 분명히 부정적인 영향을 미칩니다. 다음 조건에 해당하는 프로세스가 가시적 프로세스로 간주됩니다.
- 프로세스가 화면상으로는 사용자에게 표시되지만 포그라운드에 있지 않은
Activity
를 실행 중입니다 (onPause()
메서드가 호출되었음). 예를 들어 포그라운드 Activity
가 이전 Activity
가 뒤에 보이도록 대화상자로 표시되는 경우 이러한 상황이 발생할 수 있습니다.
- 프로세스에
Service.startForeground()
를 통해 포그라운드 서비스로 실행 중인 Service
가 있습니다(Service.startForeground()는 서비스를 사용자가 알고 있는 것 또는 기본적으로 표시되는 것처럼 처리하도록 시스템에 요청함).
- 프로세스가 시스템에서 라이브 배경화면, 입력 방법 서비스 등과 같이 사용자가 알고 있는 특정 기능에 사용하는 서비스를 호스팅하고 있습니다.
시스템에서 실행 중인 이러한 프로세스의 수는 포그라운드 프로세스보다 덜 제한적이지만 그럼에도 비교적 관리되는 편입니다. 이러한 프로세스는 매우 중요한 것으로 간주되며 프로세스의 종료가 모든 포그라운드 프로세스의 실행 상태를 유지하는 데 필요한 상황이 아니라면 종료되지 않습니다.
- 서비스 프로세스는
startService()
메서드로 시작된 Service
를 유지하는 프로세스입니다. 이러한 프로세스는 사용자에게 직접 표시되지 않지만 일반적으로 사용자가 중요하게 생각하는 작업 (예: 백그라운드 네트워크 데이터 업로드 또는 다운로드)을 실행하므로 모든 포그라운드 및 표시 프로세스를 유지하기에 메모리가 충분하지 않은 경우가 아니라면 시스템은 항상 이러한 프로세스를 실행 상태로 유지합니다.
오랫동안 (예: 30분 이상) 실행되고 있는 서비스는 중요도가 강등됨에 따라 이 프로세스가 캐시된 목록으로 이전될 수 있습니다.
장기간 실행해야 하는 프로세스는 setForeground
로 만들 수 있습니다.
엄격한 실행 시간이 필요한 주기적 프로세스인 경우 AlarmManager
를 통해 예약할 수 있습니다.
자세한 내용은 장기 실행 작업자 지원을 참고하세요.
이렇게 하면 메모리 누출과 같이 과도한 리소스를 사용하는 장기 실행 서비스가 시스템이 우수한 사용자 환경을 제공하지 못하게 하는 상황을 방지할 수 있습니다.
- 캐시된 프로세스는 현재 필요하지 않은 프로세스입니다. 따라서 시스템은 다른 곳에서 메모리와 같은 리소스가 필요할 때 언제든지 원하는 대로 이 프로세스를 종료할 수 있습니다. 정상적으로 작동하는 시스템에서 리소스 관리와 관련된 유일한 프로세스입니다.
제대로 운영되는 시스템에서는 애플리케이션 간에 효율적으로 전환할 수 있도록 항상 여러 개의 캐시된 프로세스가 사용 가능하며 필요에 따라 캐시된 앱을 정기적으로 종료합니다.
매우 심각한 상황에서만 시스템이 캐시된 프로세스를 모두 종료하고 서비스 프로세스 종료를 시작해야 하는 시점에 이르게 됩니다.
캐시된 프로세스는 언제든지 시스템에 의해 종료될 수 있으므로 앱은 캐시된 상태에서 모든 작업을 중지해야 합니다. 앱에서 사용자에게 중요한 작업을 실행해야 하는 경우 위 API 중 하나를 사용하여 활성 프로세스 상태에서 작업을 실행해야 합니다.
캐시된 프로세스는 현재 사용자에게 표시되지 않는 하나 이상의 Activity
인스턴스를 포함하는 경우가 많습니다 (onStop()
메서드가 호출되어 반환되었음).
시스템에서 이러한 프로세스를 종료할 때 Activity
수명 주기를 올바르게 구현하면 해당 앱으로 돌아갈 때 사용자 환경에 영향을 미치지 않습니다. 연결된 활동이 새 프로세스에서 다시 생성될 때 이전에 저장된 상태를 복원할 수 있습니다. 시스템에서 프로세스를 종료하는 경우 onDestroy()
가 호출되지 않을 수 있습니다.
자세한 내용은 Activity
를 참고하세요.
Android 13부터 앱 프로세스는 위의 활성 수명 주기 상태 중 하나로 전환될 때까지 제한된 실행 시간 또는 실행 시간을 전혀 받지 못할 수 있습니다.
캐시된 프로세스는 목록에 보관됩니다. 이 목록의 정확한 순서 지정 정책은 플랫폼의 구현 세부정보입니다. 일반적으로 다른 유형의 프로세스보다 사용자의 홈 애플리케이션을 호스팅하는 프로세스 또는 사용자가 마지막으로 본 활동과 같이 더 유용한 프로세스를 유지하려고 합니다. 허용되는 프로세스 수에 엄격한 제한을 설정하거나 프로세스가 지속적으로 캐시된 상태를 유지할 수 있는 시간의 제한 등 프로세스 종료에 관한 다른 정책도 적용할 수 있습니다.
프로세스 분류 방법을 결정할 때 시스템은 프로세스에서 현재 활성 상태인 모든 구성요소 중 가장 높은 중요도에 따라 결정을 내립니다.
이러한 각 구성요소가 프로세스와 애플리케이션의 전체 수명 주기에 기여하는 방식에 관한 자세한 내용은 Activity
, Service
, BroadcastReceiver
문서를 참고하세요.
프로세스의 우선순위는 프로세스가 가지고 있는 다른 종속성에 따라 증가할 수도 있습니다. 예를 들어 프로세스 A가 Context.BIND_AUTO_CREATE
플래그를 사용하여 Service
에 결합되었거나 프로세스 B의 ContentProvider
를 사용하고 있다면 프로세스 B의 분류는 항상 프로세스 A의 분류 이상으로 중요합니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[null,null,["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Processes and app lifecycle\n\nIn most cases, every Android application runs in its own Linux process.\nThis process is created for the application when some of its code needs to\nrun and remains running until the system needs to reclaim its memory for use\nby other applications and it is no longer needed.\n\nAn unusual and fundamental feature of Android is that an application process's\nlifetime *isn't* directly controlled by the application itself.\nInstead, it is determined by the system through a combination of the parts of the application\nthat the system knows are running, how important these things are to the user,\nand how much overall memory is available in the system.\n\nIt is important that\napplication developers understand how different application components\n(in particular [Activity](/reference/android/app/Activity), [Service](/reference/android/app/Service),\nand [BroadcastReceiver](/reference/android/content/BroadcastReceiver)) impact the lifetime\nof the application's process. **Not using these components correctly can\nresult in the system killing the application's process while it is doing\nimportant work.**\n\nA common example of a process lifecycle bug is a\n`BroadcastReceiver` that starts a thread when it\nreceives an `Intent` in its [BroadcastReceiver.onReceive()](/reference/android/content/BroadcastReceiver#onReceive(android.content.Context, android.content.Intent))\nmethod and then returns from the function. Once it returns, the system\nconsiders the `BroadcastReceiver` to no longer be active, and its hosting\nprocess to no longer be needed, unless other application components are active in\nit.\n\n\nSo, the system can kill the process at any time to reclaim memory, and in doing so,\nit terminates the spawned thread running in the process. The solution to this problem\nis typically to schedule a [JobService](/reference/android/app/job/JobService)\nfrom the `BroadcastReceiver` so the\nsystem knows that there is active work occurring in the process.\n\nTo determine which processes to kill when low on memory, Android\nplaces each process into an importance hierarchy based on the components running in\nthem and the state of those components. In order of importance, these process types are:\n\n1. A **foreground process** is one that is required for what the user is currently doing. Various application components can cause its containing process to be considered foreground in different ways. A process is considered to be in the foreground if any of the following conditions hold:\n - It is running an [Activity](/reference/android/app/Activity) at the top of the screen that the user is interacting with (its [onResume()](/reference/android/app/Activity#onResume()) method has been called).\n - It has a [BroadcastReceiver](/reference/android/content/BroadcastReceiver) that is currently running (its [BroadcastReceiver.onReceive()](/reference/android/content/BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)) method is executing).\n - It has a [Service](/reference/android/app/Service) that is currently executing code in one of its callbacks ([Service.onCreate()](/reference/android/app/Service#onCreate()), [Service.onStart()](/reference/android/app/Service#onStart(android.content.Intent, int)), or [Service.onDestroy()](/reference/android/app/Service#onDestroy())).\n2. There are only ever a few such processes in the system, and these are only killed as a last resort if memory is so low that not even these processes can continue to run. Generally, if this happens the device has reached a memory paging state, so this action is required to keep the user interface responsive.\n3. A **visible process** is doing work that the user is currently aware of, so killing it has a noticeable negative impact on the user experience. A process is considered visible in the following conditions:\n - It is running an [Activity](/reference/android/app/Activity) that is visible to the user on-screen but not in the foreground (its [onPause()](/reference/android/app/Activity#onPause()) method has been called). This might occur, for example, if the foreground `Activity` is displayed as a dialog that lets the previous `Activity` be seen behind it.\n - It has a [Service](/reference/android/app/Service) that is running as a foreground service, through [Service.startForeground()](/reference/android/app/Service#startForeground(int, android.app.Notification)) (which asks the system to treat the service as something the user is aware of, or essentially as if it were visible).\n - It is hosting a service that the system is using for a particular feature that the user is aware of, such as a live wallpaper or an input method service.\n\n The number of these processes running in the system is less bounded than foreground\n processes, but still relatively controlled. These processes are\n considered extremely important and aren't killed unless doing so is\n required to keep all foreground processes running.\n4. A **service process** is one holding a [Service](/reference/android/app/Service) that has been started with the [startService()](/reference/android/content/Context#startService(android.content.Intent)) method. Though these processes are not directly visible to the user, they are generally doing things that the user cares about (such as background network data upload or download), so the system always keeps such processes running unless there is not enough memory to retain all foreground and visible processes.\n\n Services that have been running for a long time (such as 30 minutes or more) might be\n demoted in importance to let their process drop to the cached list.\n\n Processes that do need to be run over a long period can be created with\n [setForeground](/reference/kotlin/androidx/work/CoroutineWorker#setForeground(androidx.work.ForegroundInfo)).\n If it is a periodic process that requires strict time of execution, it can be\n scheduled through the [AlarmManager](/reference/android/app/AlarmManager).\n For more information, refer to [Support for long-running workers](/topic/libraries/architecture/workmanager/advanced/long-running).\n This helps avoid situations where long-running services that use excessive resources, for\n example, by leaking memory, prevent the system from delivering a good user experience.\n5. A **cached process** is one that is not currently needed, so the system is free to kill it as needed when resources like memory are needed elsewhere. In a normally behaving system, these are the only processes involved in resource management.\n\n \u003cbr /\u003e\n\n A well-running system has multiple cached processes always available, for efficient\n switching between applications, and regularly kills the cached apps as needed.\n Only in very critical situations does the system get to a point where\n all cached processes are killed and it must start killing service processes.\n\n Since cached processes can be killed by the system at any time, apps should cease all work while\n in the cached state. If user-critical work must be performed by the app,\n it should use one of the above APIs to run work from an active process state.\n\n Cached processes often hold one or more [Activity](/reference/android/app/Activity) instances\n that are not currently visible to the user (their\n [onStop()](/reference/android/app/Activity#onStop()) method has been called and has returned).\n Provided they implement their `Activity` lifecycle correctly when the system\n kills such processes, it doesn't impact the user's experience when returning to that app.\n It can restore the previously saved state when the associated activity recreates in\n a new process. Be aware that [onDestroy()](/guide/components/activities/activity-lifecycle#ondestroy)\n is not guaranteed to be called in the case that a process is killed by the system.\n For more details, see [Activity](/reference/android/app/Activity).\n\n Starting in Android 13, an app process may receive limited or no execution time until it enters\n one of the above active lifecycle states.\n\n Cached processes are kept in a list. The exact ordering policy for this list\n is an implementation detail of the platform. Generally, it tries to keep more\n useful processes, such as those hosting the user's home application or the last activity the user saw,\n before other types of processes. Other policies for killing processes can also\n be applied, like setting hard limits on the number of processes allowed or limiting the amount of\n time a process can stay continually cached.\n\nWhen deciding how to classify a process, the system bases its decision on the most\nimportant level found among all the components currently active in the process.\nSee the [Activity](/reference/android/app/Activity), [Service](/reference/android/app/Service), and\n[BroadcastReceiver](/reference/android/content/BroadcastReceiver) documentation for more detail on how\neach of these components contributes to the overall lifecycle of a process and of\nthe application.\n\nA process's priority might also be increased based on other dependencies\na process has to it. For example, if process A has bound to a\n[Service](/reference/android/app/Service) with\nthe [Context.BIND_AUTO_CREATE](/reference/android/content/Context#BIND_AUTO_CREATE)\nflag or is using a\n[ContentProvider](/reference/android/content/ContentProvider) in process B, then process B's\nclassification is always at least as important as process A's."]]