Android对Linux系统的内存管理机制进行的优化是什么

技术Android对Linux系统的内存管理机制进行的优化是什么这篇文章主要介绍“Android对Linux系统的内存管理机制进行的优化是什么”,在日常操作中,相信很多人在Android对Linux系统的内存管理机制进行

本文主要介绍“安卓对Linux系统内存管理机制的优化是什么”。在日常操作中,相信很多人对于Android对Linux系统内存管理机制的优化是什么有所怀疑。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“安卓对Linux系统内存管理机制的优化是什么”的疑惑!接下来,请和边肖一起学习!

安卓也是以“最大利用”的方式使用内存,继承了Linux的优势。唯一不同的是,Linux侧重于缓存尽可能多的磁盘数据,以减少磁盘IO,提高系统的数据访问性能,而安卓侧重于缓存尽可能多的进程,以提高应用启动和切换速度。Linux系统会在进程活动停止后结束进程,而Android系统会将应用进程尽可能长时间的保留在内存中,直到系统需要更多的内存。正常情况下,这些保存在内存中的进程不会影响系统的整体运行速度,但是当用户再次激活它们时,会加快进程的启动速度,因为不需要重新加载接口资源,这是Android所标榜的特性之一。因此,安卓现在不建议明确“退出”应用。

为什么在内存不足的情况下运行大型程序会很慢?原因是内存不足时打开大程序会触发系统自己的进程调度策略,这是一个消耗系统资源的操作,尤其是当一个程序频繁向系统申请内存时。在这种情况下,系统不会关闭所有打开的进程,而是有选择地关闭,频繁的调度自然会使系统变慢。

00-1010说到安卓的内存管理,就不得不提进程管理,因为进程管理肯定会影响系统内存。在了解流程管理之前,我们先了解一些基本概念。

当一个应用程序组件启动,并且该应用程序没有运行任何其他组件时,安卓系统将使用单个执行线程为该应用程序启动一个新的Linux进程。默认情况下,同一应用程序的所有组件都在同一进程和线程(称为“主线程”)中运行。如果一个应用程序组件启动,并且该应用程序已经有一个进程(因为该应用程序还有其他组件),那么该组件将在这个进程中启动,并使用相同的执行线程。但是,您也可以安排应用程序中的其他组件在单独的进程中运行,并为任何进程创建额外的线程。

安卓应用模型的设计思路取自Web 2.0的Mashup概念,是一种基于组件的应用设计模式。在这个模型中,每个应用程序由一系列组件构建,组件通过应用程序配置文件描述功能。安卓系统根据组件的配置信息,了解各个组件的功能,进行统一调度。这意味着来自不同应用程序的组件可以有机地组合在一起,共同完成任务。每个安卓应用只有明确的组件边界,没有明确的流程边界和应用边界。这种设计也使开发者能够致力于核心功能的开发,而不是花费精力重新开发一些辅助功能。这不仅提高了应用程序开发的效率,而且增强了用户体验(例如,在电子邮件中选择图片作为附件的功能可以直接调用特殊图片应用程序的功能,而不必从头开发)。

系统不会为每个组件实例创建单独的线程。同一进程中运行的所有组件都在UI线程中实例化,对每个组件的系统调用都由该线程调度。因此,响应系统回调的方法(例如,onKeyDown()或报告用户操作的生命周期回调方法)总是在进程的UI线程中运行(四个组件的所有生命周期回调方法都在UI线程中触发)。

Android中的进程管理

安卓的一个不寻常的基本特征是,应用程序进程的生命周期不是由应用程序本身直接控制的。相反,进程的生命周期是由系统决定的,系统将权衡每个进程对用户的相对重要性和系统的总可用内存。例如,系统更有可能终止托管不再在屏幕上可见的活动的进程,而不是终止托管与用户交互的活动的进程,否则后果是可怕的。因此,是否终止进程取决于进程中运行的组件的状态。安卓将清理那些不再以有限的方式使用的进程,以确保最小的副作用。

作为应用程序开发人员,了解每个应用程序组件(尤其是活动、服务和广播接收器)如何影响应用程序流程的生命周期非常重要。当应用程序执行重要工作时,不当使用这些组件可能会导致系统终止进程。

举个常见的例子,当BroadcastReceiver在其onReceive()方法中接收到Intent时,它会启动一个线程,然后从这个函数中返回它。一旦返回,系统会假设BroadcastReceiver不再活动,因此不再需要它的托管进程(除非进程中的其他组件处于活动状态)。这样,系统可以随时终止进程以回收内存,这最终将导致进程中运行的线程终止。这个问题的解决方案通常是从BroadcastReceiver中安排一个JobService,这样系统就可以知道进程中仍然有活动的作业。

为了确定内存不足时终止哪些进程,Android会根据进程中正在运行的组件以及这些组件的状态,将每个进程放入“重要性层次”。必要时,系统将首先杀死重要性最低的进程,依此类推,以便返回

收系统资源。这就相当于为进程分配了优先级的概念。 

进程优先级

Foreground Process:前台进程(正常不会被杀死)

用户当前操作所必需的进程。有很多组件能以不同的方式使得其所在进程被判定为前台进程。如果一个进程满足以下任一条件,即视为前台进程:

  • 托管用户正在交互的 Activity(已调用 Activity 的 onResume() 方法)

  • 托管某个 Service,后者绑定到用户正在交互的 Activity

  • 托管正执行一个生命周期回调的 Service(onCreate()、onStart() 或 onDestroy())

  • 托管正执行其 onReceive() 方法的 BroadcastReceiver

通常,在任意给定时间前台进程都为数不多。只有在内存不足以支持它们同时继续运行这一万不得已的情况下,系统才会终止它们。此时,设备往往已达到内存分页状态,因此需要终止一些前台进程来确保用户界面正常响应。

Visible Process:可见进程(正常不会被杀死

没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。杀死这类进程也会明显影响用户体验。如果一个进程满足以下任一条件,即视为可见进程:

  • 托管不在前台、但仍对用户可见的 Activity(已调用其 onPause() 方法)。例如,启动了一个对话框样式的前台 activity ,此时在其后面仍然可以看到前一个Activity。

运行时权限对话框就属于此类。考虑一下,还有哪种情况会导致只触发onPause而不触发onStop?

  • 托管通过 Service.startForeground() 启动的前台Service。

Service.startForeground():它要求系统将它视为用户可察觉到的服务,或者基本上对用户是可见的。

  • 托管系统用于某个用户可察觉的特定功能的Service,比如动态壁纸、输入法服务等等。

可见进程被视为是极其重要的进程,除非为了维持所有前台进程同时运行而必须终止,否则系统不会终止这些进程。如果这类进程被杀死,从用户的角度看,这意味着当前 activity 背后的可见 activity 会被黑屏代替。

Service Process:服务进程(正常不会被杀死)

正在运行已使用 startService() 方法启动的服务且不属于上述两个更高类别进程的进程。尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如,后台网络上传或下载数据)。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。

已经运行很久(例如30分钟或更久)的Service,有可能被降级,这样一来它们所在的进程就可以被放入Cached LRU列表中。这有助于避免一些长时间运行的Service由于内存泄漏或其他问题而消耗过多的RAM,进而导致系统无法有效使用缓存进程的情况。

Background / Cached Process:后台进程(可能随时被杀死)

这类进程一般会持有一个或多个目前对用户不可见的 Activity (已调用 Activity 的 onStop() 方法)。它们不是当前所必须的,因此当其他更高优先级的进程需要内存时,系统可能 随时终止 它们以回收内存。但如果正确实现了Activity的生命周期,即便系统终止了进程,当用户再次返回应用时也不会影响用户体验:关联Activity在新的进程中被重新创建时可以恢复之前保存的状态。

在一个正常运行的系统中,缓存进程是内存管理中 唯一 涉及到的进程:一个运行良好的系统将始终具有多个缓存进程(为了更高效的切换应用),并根据需要定期终止最旧的进程。只有在非常严重(并且不可取)的情况下,系统才会到达这样一个点,此时所有的缓存进程都已被终止,并且必须开始终止服务进程。

Android系统回收后台进程的参考条件:

  • LRU算法:自下而上开始终止,先回收最老的进程。越老的进程近期内被用户再次使用的几率越低。杀死的进程越老,对用户体验的影响就越小。

  • 回收收益:系统总是倾向于杀死一个能回收更多内存的进程,因为在它被杀时会为系统提供更多内存增益,从而可以杀死更少的进程。杀死的进程越少,对用户体验的影响就越小。换句话说,应用进程在整个LRU列表中消耗的内存越少,保留在列表中并且能够快速恢复的机会就越大。

这类进程会被保存在一个伪LRU列表中,系统会优先杀死处于列表尾部(最老)的进程,以确保包含用户最近查看的 Activity 的进程最后一个被终止。这个LRU列表排序的确切策略是平台的实现细节,但通常情况下,相对于其他类型的进程,系统会优先尝试保留更有用的进程(比如托管用户主应用程序的进程,或者托管用户看到的最后一个Activity的进程,等等)。还有其他一些用于终止进程的策略:对允许的进程数量硬限制,对进程可以持续缓存的时间量的硬限制,等等。

在一个健康的系统中,只有缓存进程或者空进程会被系统随时终止,如果服务进程,或者更高优先级的可见进程以及前台进程也开始被系统终止(不包括应用本身糟糕的内存使用导致OOM),那就说明系统运行已经处于一个亚健康甚至极不健康的状态,可用内存已经吃紧。

Empty Process:空进程(可以随时杀死)

不含任何活跃组件的进程。保留这种进程的的唯一目的是用作缓存(为了更加有效的使用内存而不是完全释放掉),以缩短下次启动应用程序所需的时间,因为启动一个新的进程也是需要代价的。只要有需要,Android会随时杀死这些进程。

内存管理中对于前台/后台应用的定义,与用于Service限制目的的后台应用定义不同。从Android 8.0开始,出于节省系统资源、优化用户体验、提高电池续航能力的考量,系统进行了前台/后台应用的区分,对于后台service进行了一些限制。在该定义中,如果满足以下任意条件,应用将被视为处于前台:

>

  • 具有可见 Activity(不管该 Activity 已启动还是已暂停)。

  • 具有前台 Service。

  • 另一个前台应用已关联到该应用(不管是通过绑定到其中一个 Service,还是通过使用其中一个内容提供程序)。例如,如果另一个应用绑定到该应用的 Service,那么该应用处于前台:IME 壁纸 Service 通知侦听器 语音或文本 Service 如果以上条件均不满足,应用将被视为处于后台。 

Android系统如何评定进程的优先级

根据进程中当前活动组件的重要程度,Android 会将进程评定为它可能达到的最高级别。 例如,如果某进程同时托管着 Service 和可见 Activity,则会将此进程评定为可见进程,而不是服务进程。

此外,一个进程的级别可能会因其他进程对它的依赖而有所提高,即服务于另一进程的进程其级别永远不会低于其所服务的进程。 例如,如果进程 A 中的内容提供程序为进程 B 中的客户端提供服务,或者如果进程 A 中的服务绑定到进程 B 中的组件,则进程 A 始终被视为至少与进程 B 同样重要。

由于运行服务的进程其级别高于托管后台 Activity 的进程,因此,在 Activity 中启动一个长时间运行的操作时,最好为该操作启动服务,而不是简单地创建工作线程,当操作有可能比 Activity 更加持久时尤要如此。例如,一个文件上传的操作就可以考虑使用服务来完成,这样一来,即使用户退出 Activity,仍可在后台继续执行上传操作。使用服务可以保证,无论 Activity 发生什么情况,该操作至少具备“服务进程”优先级。同理, BroadcastReceiver 也应使用服务,而不是简单地将耗时冗长的操作放入线程中。 

Home键退出和返回键退出的区别

Home键退出,程序保留状态为后台进程;而返回键退出,程序保留状态为空进程,空进程更容易被系统回收。Home键其实主要用于进程间切换,返回键则是真正的退出程序。

从理论上来讲,无论是哪种情况,在没有任何后台工作线程(即便应用处于后台,工作线程仍然可以执行)的前提下,被置于后台的进程都只是保留他们的运行状态,并不会占用CPU资源,所以也不耗电。只有音乐播放软件之类的应用需要在后台运行Service,而Service是需要占用CPU时间的,此时才会耗电。所以说没有带后台服务的应用是不耗电也不占用CPU时间的,没必要关闭,这种设计本身就是Android的优势之一,可以让应用下次启动时更快。然而现实是,很多应用多多少少都会有一些后台工作线程,这可能是开发人员经验不足导致(比如线程未关闭或者循环发送的Handler消息未停止),也可能是为了需求而有意为之,导致整个Android应用的生态环境并不是一片干净。

到此,关于“Android对Linux系统的内存管理机制进行的优化是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/126279.html

(0)

相关推荐

  • 端午节的简介50字,端午节的来历30字左右

    技术端午节的简介50字,端午节的来历30字左右战国时期的楚国(今湖北)诗人屈原在该日抱石跳汨罗江自尽端午节的简介50字,统治者为树立忠君爱国标签将端午作为纪念屈原的节日;部分地区也有纪念伍子胥、曹娥等说法。
    端午节与春节

    生活 2021年10月22日
  • 5.循环

    技术5.循环 5.循环循环循环就是让相同的代码块一次又一次地重复运行1.while循环
    语法 :
    while (条件)
    {要执行的代码;
    }实例 :
    php$i = 1;while ($i = 5) {

    礼包 2021年12月23日
  • 别看今天闹得欢,为什么现在肺癌越来越多

    技术别看今天闹得欢,为什么现在肺癌越来越多一说肺癌别看今天闹得欢,立马联想到吸烟。的确,如果一个人烟瘾大,一枝接着一枝的吸,那么会是一口接着一口吸的是烟气,而不是清新的空气。试想 ,会对肺部该有多大的损害。在吸烟如命人的

    生活 2021年10月25日
  • 外部css样式表的作用是什么

    技术外部css样式表的作用是什么本篇内容主要讲解“外部css样式表的作用是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“外部css样式表的作用是什么”吧!

    攻略 2021年11月3日
  • MongoDB Query的命令行分别是哪些

    技术MongoDB Query的命令行分别是哪些这期内容当中小编将会给大家带来有关MongoDB Query的命令行分别是哪些,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Query.

    攻略 2021年11月3日
  • 春卷的馅料有哪些,粽子有哪些馅料粽子馅料种类

    技术春卷的馅料有哪些,粽子有哪些馅料粽子馅料种类粽子的口味很多春卷的馅料有哪些,馅料相当丰富,除了传统的鲜肉粽、豆沙粽、蛋黄肉粽、红枣粽、板栗粽、莲子粽外,还有百果粽、紫薯粽、桂花飘香粽、鲍汁牛柳粽、干贝鲜肉粽,等等。凡

    生活 2021年10月31日