Android Process Scheduling
I am trying to get a better understanding so I can scope the reliability impact from potential interoperability issues when creating an android app/service. I would like to figure out how process priority is determined. The differences in priority between services and activities and if the scheduler treats their priority differently. Basically I'm trying to get a strong understanding of how likely it is that an activity or service is starved by a rogue processes from a different application (or even the linux kernel.)
Does anyone have any good links you could recommend... My searches haven't turned up much, yet.
Thanks!
Edit: My concern is with regard to processor time slicing/scheduling, not memory resources (memory resources are well described within the android documentation.) Thanks again!
Solution 1:
The following list presents the different types of processes in order of importance (the first process is most important and is killed last):
- Foreground process
- Visible process
- Service process
- Background process
- Empty process
Note: Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process is ranked as a visible process, not a service process.
This is referenced from here Processes and Threads
EDIT:
Understanding Application Priority and Process States
The order in which processes are killed to reclaim resources is determined by the priority of the hosted applications. An application’s priority is equal to its highest-priority component.
Where two applications have the same priority, the process that has been at a lower priority longest will be killed first. Process priority is also affected by interprocess dependencies; if an application has a dependency on a Service or Content Provider supplied by a second application, the secondary application will have at least as high a priority as the application it supports.
All Android applications will remain running and in memory until the system needs its resources for other applications.
It’s important to structure your application correctly to ensure that its priority is appropriate for the work it’s doing. If you don’t, your application could be killed while it’s in the middle of something important. The following list details each of the application states shown in Figure , explaining how the state is determined by the application components comprising it:
Active Processes Active (foreground) processes are those hosting applications with components currently interacting with the user. These are the processes Android is trying to keep responsive by reclaiming resources. There are generally very few of these processes, and they will be killed only as a last resort.
Active processes include:
1.Activities in an “active” state; that is, they are in the foreground and responding to user events. You will explore Activity states in greater detail later in this chapter.
2.Activities, Services, or Broadcast Receivers that are currently executing an onReceive event handler.
3.Services that are executing an onStart, onCreate, or onDestroy event handler.
Visible Processes Visible, but inactive processes are those hosting “visible” Activities. As the name suggests, visible Activities are visible, but they aren’t in the foreground or responding to user events. This happens when an Activity is only partially obscured (by a non-full-screen or transparent Activity). There are generally very few visible processes, and they’ll only be killed in extreme circumstances to allow active processes to continue.
Started Service Processes Processes hosting Services that have been started. Services support ongoing processing that should continue without a visible interface. Because Services don’t interact directly with the user, they receive a slightly lower priority than visible Activities. They are still considered to be foreground processes and won’t be killed unless resources are needed for active or visible processes.
Background Processes Processes hosting Activities that aren’t visible and that don’t have any Services that have been started are considered background processes. There will generally be a large number of background processes that Android will kill using a last-seen-first-killed pat- tern to obtain resources for foreground processes.
Empty Processes To improve overall system performance, Android often retains applications in memory after they have reached the end of their lifetimes. Android maintains this cache to improve the start-up time of applications when they’re re-launched. These processes are rou- tinely killed as required.
For more info look at here(I found on this blog) Memory Management in Android
EDIT:
I think Android is basic Linux so, whatever scheduler works for Linux is same in Android.
The difference between Android scheduler and Linux scheduler
Scheduler — 5 files — The Android kernel also contains slight changes to the CPU process scheduler and time-keeping algorithms. We don’t know the history of these changes, and the impact was not evident based on a cursory examination.
Process Preemption:
As mentioned, the Linux operating system is preemptive. When a process enters the TASK_RUNNING state, the kernel checks whether its priority is higher than the priority of the currently executing process. If it is, the scheduler is invoked to pick a new process to run (presumably the process that just became runnable). Additionally, when a process's timeslice reaches zero, it is preempted, and the scheduler is invoked to select a new process.
The Scheduling Policy in Action
Consider a system with two runnable tasks: a text editor and a video encoder. The text editor is I/O-bound because it spends nearly all its time waiting for user key presses (no matter how fast the user types, it is not that fast). Despite this, when it does receive a key press, the user expects the editor to respond immediately. Conversely, the video encoder is processor-bound. Aside from reading the raw data stream from the disk and later writing the resulting video, the encoder spends all its time applying the video codec to the raw data. It does not have any strong time constraints on when it runs—if it started running now or in half a second, the user could not tell. Of course, the sooner it finishes the better.
In this system, the scheduler gives the text editor a higher priority and larger timeslice than the video encoder, because the text editor is interactive. The text editor has plenty of timeslice available. Furthermore, because the text editor has a higher priority, it is capable of preempting the video encoder when needed. This ensure the text editor is capable of responding to user key presses immediately. This is to the detriment of the video encoder, but because the text editor runs only intermittently, the video encoder can monopolize the remaining time. This optimizes the performance of both applications.
Solution 2:
Android in this regard is a little different than a normal Linux system. There are two things Android uses to impact scheduling: process/thread "nice" level and cgroups.
The process "nice" level impacts the normal "fair" scheduling policy of Linux; threads that have a higher niceness will be run less often than threads with a lower niceness. In the situation where you have one thread at a "default" priority (as defined in Process.THREAD_PRIORITY_DEFAULT
) will get to run significantly more often than those at a background priority (or Process.THREAD_PRIORITY_BACKGROUND
).
In theory this can make sure that the foreground/UI threads aren't impacted significantly by background work... however, in practice, it isn't sufficient. Consider if you have 10 background threads all wanting to run, but one foreground thread driving the UI. This can still result in noticeable impact on the behavior of the foreground thread.
To address this, Android also uses Linux cgroups in a simple way to create more strict foreground vs. background scheduling. The foreground/default cgroup allows thread scheduling as normal. The background cgroup however applies a limit of only some small percent of the total CPU time being available to all threads in that cgroup. Thus if that percentage is 5% and you have 10 background threads all wanting to run and one foreground thread, the 10 background threads together can only take at most 5% of the available CPU cycles from the foreground. (Of course if no foreground thread wants to run, the background threads can use all of the available CPU cycles.)
Android implicitly moves threads between the default and background cgroups when you use its public APIs to set the thread priority. Thus if you set a thread's priority to Process.THREAD_PRIORITY_BACKGROUND
or greater, you will also be putting the thread into the background cgroup. Set it to Process.THREAD_PRIORITY_DEFAULT
and it will be in the default cgroup.
Because of this, by following the normal convention of putting your background worker threads into the background priority you can ensure that they do not disrupt your foreground UI thread.
In addition, Android will also move all threads in a process to the background cgroup for processes that it knows are not critical to the user. Any background process or service process has its threads put into the background cgroup, regardless of whether individual threads have requested a foreground scheduling priority.
Solution 3:
Yes, it's possible for your process to be starved.
Android uses Linux 2.6 for its low level management of resources. Linux 2.6 happens to use multi-level feedback queues as its scheduling algorithm. This favours I/O bound processes and short CPU burst processes (ideal for phones for responsiveness/interaction). This does however mean that CPU intensive processes and low priority processes risk getting starved. I'm not sure if Linux 2.6 periodically increases the priority of waiting processes so they will eventually get served thereby avoiding starvation.
Realistically though, you shouldn't need to worry about this since you will either be the active activity or you will be a service, both of which have relatively high priorities as the previous answer shows.