35

我试图更好地理解,以便在创建 android 应用程序/服务时确定潜在互操作性问题对可靠性的影响。我想弄清楚如何确定进程优先级。服务和活动之间的优先级差异,以及调度程序是否以不同方式处理它们的优先级。基本上,我试图深入了解活动或服务被来自不同应用程序(甚至是 linux 内核)的流氓进程饿死的可能性有多大。

有没有人有任何你可以推荐的好链接...我的搜索还没有出现太多。

谢谢!

编辑:我关心的是处理器时间切片/调度,而不是内存资源(内存资源在 android 文档中有很好的描述。)再次感谢!

4

3 回答 3

47

以下列表按重要性顺序列出了不同类型的进程(第一个进程最重要,最后被杀死):

  1. 前台进程
  2. 可见过程
  3. 服务流程
  4. 后台进程
  5. 空进程

注意: Android 根据进程中当前活动组件的重要性,将进程排在它所能达到的最高级别。例如,如果一个进程承载一个服务和一个可见活动,则该进程被列为可见进程,而不是服务进程。

这是从这里引用的Processes and Threads

编辑:

了解应用程序优先级和进程状态

进程被杀死以回收资源的顺序由托管应用程序的优先级决定。应用程序的优先级等于其最高优先级的组件。

如果两个应用程序具有相同的优先级,则优先级较低的进程将首先被杀死。进程优先级也受进程间依赖的影响;如果一个应用程序依赖于第二个应用程序提供的服务或内容提供程序,则第二个应用程序将至少具有与其支持的应用程序一样高的优先级。

所有 Android 应用程序将保持运行并在内存中,直到系统需要其资源用于其他应用程序。

正确构建应用程序以确保其优先级适合其正在执行的工作非常重要。如果你不这样做,你的应用程序可能会在它处于重要的中间时被杀死。以下列表详细说明了图 中所示的每个应用程序状态,解释了状态是如何由组成它的应用程序组件确定的:

活动进程活动(前台)进程是那些托管应用程序的进程,这些应用程序具有当前与用户交互的组件。这些是 Android 试图通过回收资源来保持响应的过程。这些进程一般很少,只有在万不得已的情况下才会被杀死。

在此处输入图像描述

活动进程包括:

1.处于“活跃”状态的活动;也就是说,它们处于前台并响应用户事件。您将在本章后面更详细地探索活动状态。

2.当前正在执行 onReceive 事件处理程序的活动、服务或广播接收器。

3. 正在执行 onStart、onCreate 或 onDestroy 事件处理程序的服务。

可见流程可见但不活动的流程是那些托管“可见”活动的流程。顾名思义,可见活动是可见的,但它们不在前台或响应用户事件。当 Activity 仅被部分遮挡(被非全屏或透明 Activity)遮挡时,就会发生这种情况。通常可见的进程很少,它们只会在极端情况下被杀死以允许活动进程继续。

已启动的服务进程 托管已启动服务的进程。服务支持正在进行的处理,该处理应该在没有可见界面的情况下继续进行。因为服务不直接与用户交互,所以它们接收的优先级比可见活动略低。它们仍然被认为是前台进程并且不会被杀死,除非活动或可见进程需要资源。

后台进程托管不可见且没有任何已启动服务的活动的进程被视为后台进程。通常会有大量后台进程被 Android 使用最后看到的先被杀死的模式杀死,以获取前台进程的资源。

空进程为了提高整体系统性能,Android 通常会在应用程序的生命周期结束后将它们保留在内存中。Android 会维护此缓存以缩短应用程序重新启动时的启动时间。这些进程会根据需要定期终止。

有关更多信息,请查看此处(我在此博客上找到)Android 中的内存管理

编辑:

I think Android is basic Linux so, whatever scheduler works for Linux is same in Android. 

Android调度器和Linux调度器的区别

调度程序 — 5 个文件 — Android 内核还包含对 CPU 进程调度程序和计时算法的细微更改。我们不知道这些变化的历史,根据粗略的检查,影响并不明显。

进程抢占:

如前所述,Linux 操作系统是抢占式的。当一个进程进入TASK_RUNNING状态时,内核会检查它的优先级是否高于当前正在执行的进程的优先级。如果是,则调用调度程序来选择要运行的新进程(可能是刚刚变为可运行的进程)。此外,当一个进程的时间片达到零时,它会被抢占,并调用调度程序来选择一个新进程。

调度策略在行动

考虑一个具有两个可运行任务的系统:一个文本编辑器和一个视频编码器。文本编辑器是 I/O 密集型的,因为它几乎所有时间都在等待用户按键(无论用户键入多快,它都不是那么快)。尽管如此,当它确实收到按键时,用户希望编辑器立即响应。相反,视频编码器受处理器限制。除了从磁盘读取原始数据流并随后写入生成的视频之外,编码器将所有时间都用于将视频编解码器应用于原始数据。它对何时运行没有任何严格的时间限制——是现在开始运行还是半秒后开始运行,用户无法判断。当然,越早结束越好。

在这个系统中,调度器赋予文本编辑器比视频编码器更高的优先级和更大的时间片,因为文本编辑器是交互式的。文本编辑器有大量可用的时间片。此外,由于文本编辑器具有更高的优先级,它能够在需要时抢占视频编码器。这确保了文本编辑器能够立即响应用户按键。这对视频编码器是不利的,但由于文本编辑器只是间歇性地运行,视频编码器可以独占剩余的时间。这优化了两个应用程序的性能。

于 2011-10-28T15:09:31.020 回答
36

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.

于 2011-11-09T04:39:49.847 回答
8

是的,您的进程可能会被饿死。

Android 使用 Linux 2.6进行低级资源管理。Linux 2.6 恰好使用多级反馈队列作为其调度算法。这有利于 I/O 绑定进程和短 CPU 突发进程(非常适合用于响应/交互的手机)。然而,这确实意味着 CPU 密集型进程和低优先级进程有被饿死的风险。我不确定 Linux 2.6 是否会定期增加等待进程的优先级,以便它们最终得到服务,从而避免饥饿。

但实际上,您不必担心这一点,因为您将成为活跃的活动或服务,正如前面的答案所示,两者都具有相对较高的优先级。

于 2011-11-07T21:11:17.740 回答