Android system — 进程生命周期与ADJ
Android system — 进程oom_adj
- 0. 引言
- 1. 进程的生命周期
- 1.1 Foreground process
- 1.2 Visible process
- 1.3 Service process
- 1.4 Background process
- 1.5 Empty process
- 2. Lowmemorykiller
- 2.1 ADJ级别
- 2.2 进程state级别
- 2.3 lmk策略
- 2.4 如何查看应用oom_adj值
- 3. 注意
0. 引言
本文主要介绍Android的lowmemorykiller的oom_adj的相关概念,进程的oom_adj,决定了当内存不够的时候,lmk会根据oom_adj的级别依次释放内存。哪怕做为应用开发者,对于进程生命周期和进程中的内存回收是透明的,但了解生命周期对加深对Andorid体系的理解很有帮助
1. 进程的生命周期
Android系统将尽量长时间地保持应用进程,但为了新建进程或运行更重要的进程,最终需要清除旧进程来回收内存。 为了确定保留或终止哪些进程,系统会根据进程中正在运行的组件以及这些组件的状态,将每个进程放入“重要性层次结构”中。 必要时,系统会首先消除重要性最低的进程,然后是清除重要性稍低一级的进程,依此类推,以回收系统资源。
进程的重要性,划分5级:
- 前台进程(Foreground process)
- 可见进程(Visible process)
- 服务进程(Service process)
- 后台进程(Background process)
- 空进程(Empty process)
前台进程的重要性最高,依次递减,空进程的重要性最低,下面分别来阐述每种级别的进程
1.1 Foreground process
用户当前操作所必需的进程。通常在任意给定时间前台进程都为数不多。只有在内存不足以支持它们同时继续运行这一万不得已的情况下,系统才会终止它们。
- 拥有用户正在交互的 Activity(已调用onResume())
- 拥有某个 Service,后者绑定到用户正在交互的 Activity
- 拥有正在“前台”运行的 Service(服务已调用 startForeground())
- 拥有正执行一个生命周期回调的 Service(onCreate()、onStart() 或 onDestroy())
- 拥有正执行其 onReceive() 方法的 BroadcastReceiver
1.2 Visible process
没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。可见进程被视为是极其重要的进程,除非为了维持所有前台进程同时运行而必须终止,否则系统不会终止这些进程。
- 拥有不在前台、但仍对用户可见的 Activity(已调用onPause())。
- 拥有绑定到可见(或前台)Activity 的 Service
1.3 Service process
尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如,在后台播放音乐或从网络下载数据)。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。
- 正在运行startService()方法启动的服务,且不属于上述两个更高类别进程的进程。
1.4 Background process
后台进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程、可见进程或服务进程使用。 通常会有很多后台进程在运行,因此它们会保存在LRU列表中,以确保包含用户最近查看的Activity的进程最后一个被终止。如果某个 Activity 正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该 Activity 时,Activity 会恢复其所有可见状态。
- 对用户不可见的Activity的进程(已调用Activity的onStop()方法)
1.5 Empty process
保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。 为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程。
- 不含任何活动应用组件的进程
2. Lowmemorykiller
Android中对于内存的回收,主要依靠Lowmemorykiller来完成,是一种根据阈值级别触发相应力度的内存回收的机制。
2.1 ADJ级别
在Android的lowmemroykiller机制中,会对于所有进程进行分类,对于每一类别的进程会有其oom_adj值的取值范围,oom_adj值越高则代表进程越不重要,在系统执行低杀操作时,会从oom_adj值越高的开始杀。系统lowmemeorykiller机制下对于进程的级别的以变量的形式定义在framework/base/services/core/java/com/android/server/am/ProcessList.java类中,可总结成下表:
| adj级别 | 值 | 说明 |
|---|---|---|
| UNKNOWN_ADJ | 16 | 预留的最低级别,一般指将要会缓存进程,无法获取确定值 |
| CACHED_APP_MAX_ADJ | 15 | 不可见进程的adj最大值 1 |
| CACHED_APP_MIN_ADJ | 9 | 不可见进程的adj最小值 2 |
| SERVICE_B_ADJ | 8 | B List中的Service(较老的、使用可能性更小) |
| PREVIOUS_APP_ADJ | 7 | 上一个App的进程(往往通过按返回键) |
| HOME_APP_ADJ | 6 | Home进程 |
| SERVICE_ADJ | 5 | 服务进程(Service process) |
| HEAVY_WEIGHT_APP_ADJ | 4 | 后台的重量级进程,system/rootdir/init.rc文件中设置 |
| BACKUP_APP_ADJ | 3 | 备份进程 3 |
| PERCEPTIBLE_APP_ADJ | 2 | 可感知进程,比如后台音乐播放 4 |
| VISIBLE_APP_ADJ | 1 | 可见进程(Visible process) 5 |
| FOREGROUND_APP_ADJ | 0 | 前台进程(Foreground process) 6 |
| PERSISTENT_SERVICE_ADJ | -11 | 关联着系统或persistent进程 |
| PERSISTENT_PROC_ADJ | -12 | 系统persistent进程,比如telephony |
| SYSTEM_ADJ | -16 | 系统进程 |
| NATIVE_ADJ | -17 | native进程(不被系统管理) |
2.2 进程state级别
定义在ActivityManager.java文件,process_state划分18类,从-1到16之间取值。
| state级别 | 取值 | 解释 |
|---|---|---|
| PROCESS_STATE_CACHED_EMPTY | 16 | 进程处于cached状态,且为空进程 |
| PROCESS_STATE_CACHED_ACTIVITY_CLIENT | 15 | 进程处于cached状态,且为另一个cached进程(内含Activity)的client进程 |
| PROCESS_STATE_CACHED_ACTIVITY | 14 | 进程处于cached状态,且内含Activity |
| PROCESS_STATE_LAST_ACTIVITY | 13 | 后台进程,且拥有上一次显示的Activity |
| PROCESS_STATE_HOME | 12 | 后台进程,且拥有home Activity |
| PROCESS_STATE_RECEIVER | 11 | 后台进程,且正在运行receiver |
| PROCESS_STATE_SERVICE | 10 | 后台进程,且正在运行service |
| PROCESS_STATE_HEAVY_WEIGHT | 9 | 后台进程,但无法执行restore,因此尽量避免kill该进程 |
| PROCESS_STATE_BACKUP | 8 | 后台进程,正在运行backup/restore操作 |
| PROCESS_STATE_IMPORTANT_BACKGROUND | 7 | 对用户很重要的进程,用户不可感知其存在 |
| PROCESS_STATE_IMPORTANT_FOREGROUND | 6 | 对用户很重要的进程,用户可感知其存在 |
| PROCESS_STATE_TOP_SLEEPING | 5 | 与PROCESS_STATE_TOP一样,但此时设备正处于休眠状态 |
| PROCESS_STATE_FOREGROUND_SERVICE | 4 | 拥有给一个前台Service |
| PROCESS_STATE_BOUND_FOREGROUND_SERVICE | 3 | 拥有给一个前台Service,且由系统绑定 |
| PROCESS_STATE_TOP | 2 | 拥有当前用户可见的top Activity |
| PROCESS_STATE_PERSISTENT_UI | 1 | persistent系统进程,并正在执行UI操作 |
| PROCESS_STATE_PERSISTENT | 0 | persistent系统进程 |
| PROCESS_STATE_NONEXISTENT | -1 | 不存在的进程 |
2.3 lmk策略
Lowmemorykiller根据当前可用内存情况来进行进程释放,总设计了6个级别,即上表中“解释列”加粗的行,即Lowmemorykiller的杀进程的6档,如下:
- CACHED_APP_MAX_ADJ
- CACHED_APP_MIN_ADJ
- BACKUP_APP_ADJ
- PERCEPTIBLE_APP_ADJ
- VISIBLE_APP_ADJ
- FOREGROUND_APP_ADJ
系统内存从很宽裕到不足,Lowmemorykiller也会相应地从CACHED_APP_MAX_ADJ(第1档)开始杀进程,如果内存还不足,那么会杀CACHED_APP_MIN_ADJ(第2档),不断深入,直到满足内存阈值条件。
2.4 如何查看应用oom_adj值
最直观的方法,通过ps -A找到应用的pid
然后 cat /proc/$pid/oom_score_adj 即可
3. 注意
过多的调整OOM adjusted score 会导致OOM Killer选中进程的过程变得随机,而且没有足够的内存被释放掉。解决内存不足的最好办法还是增加可用内存(例如更好的硬件)或者将某些进程移到别的地方去,又或者优化代码以减少内存消耗。
相关文章:
Android system — 进程生命周期与ADJ
Android system — 进程oom_adj0. 引言1. 进程的生命周期1.1 Foreground process1.2 Visible process1.3 Service process1.4 Background process1.5 Empty process2. Lowmemorykiller2.1 ADJ级别2.2 进程state级别2.3 lmk策略2.4 如何查看应用oom_adj值3. 注意0. 引言 本文主要…...
vue3+ts+node个人博客系统(三)
一.主页顶部和中心面板布局 (1) 首先先去element-plus选择合适的布局el-container (2)在头部处编写相应的菜单栏el-menu,在这里要注意动态绑定路由的问题:default-active"$route.path"。将default-active设置为$route.path,el-me…...
Python第三方模块
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放࿰…...
怎样查询PMP成绩?
【如何查询成绩】1、输入网址(PMI官网,不知道网址的私戳),点击 Log In如果忘记 PMI 的账号和密码了,怎么办?可以在你报名机构官网的个人中心的学习中心的我的报名处查看 PMI 的注册名和密码2、点击 Exam An…...
说说变量 __name__ 和它可能取到的一个值 __main__
结合 例子 弄懂 变量__name__ 和它的值’ main’这两个东西。 首先,明白两个定义, __name__是一个变量, __main__是个普通字符串,不是变量,但可以作为变量的值。 例子: 1.py 代码如下: if _…...
软考高级-信息系统管理师之整体管理(最新版)
整体管理 1、项目整体管理概述2、制定项目章程(选择,案例,论文)制定项目章程过程制定项目章程的依据1、协议2.项目工作说明书:3、商业论证4、事业环境因素包括,但不限于如下事项。5、组织过程资产:项目选择方法项目启动会议项目目标引导技术3、制订项目管理计划(选择)项目管…...
JVM学习篇垃圾收集器ParNewCMS与底层三色标记算法详解
1. 垃圾收集算法 2. 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法…...
基于FFmpeg和Screen Capturer Recorder实现屏幕和声音的录制
当我们看到一些精彩的视频画面,但无法下载时,可以通过录屏的方式将视频和音频录制下来。 这个时候我们需要安装采集视频和音频的工具screen-capture-recorder。 以下是在windows10环境下,基于FFmpeg和Screen Capturer Recorder实现屏幕和声音…...
猿人学14题详解
目测重点在于cookie:mz和m 获取mz.js: https://match.yuanrenxue.com/static/match/match14/m.js 获取设置m: https://match.yuanrenxue.com/api/match/14/m 一、还原16进制 const fs require(fs); const parser require(babel/parser); const gen…...
Allegro如何快速把推挤的走线变平滑操作指导
Allegro如何快速把推挤的走线变平滑操作指导 Allegro有个非常强大的功能,推挤命令,可以快速的让走线以不报DRC的形式避让目标 推挤后的效果如下图 但是走线不够平滑,如果每一段都去再推一下比较费时间,下面介绍allegro本身自带的优化类似走线的功能 具体操作如下 点击Rout…...
nginx基础学习
作为前端开发者,也很有必要了解一些运维部署知识。 nginx的作用有哪些? 负载平衡动静分离反向代理 何为反向代理? 反向代理即是,用户访问nginx服务器,nginx又将请求转发到真正服务器上,为什么用户不能直…...
【HDFS】FsDatasetImpl#recoverClose方法
recoverClose的目的recoverClose的过程recoverClose的调用点一、前言 HDFS客户端写文件时,如果某个datanode发生错误或者异常。客户端会把这个datanode从pipeline里踢除,然后进行pipiline recovery,用剩余datanodes去写或者满足一定的条件时补充新的datanode到pipeline中写…...
加油站会员管理小程序实战开发教程15 完结篇
这篇是本次实战课程的最后一篇,我们在上篇还有两个问题没解决。一个是会员卡类型显示不对,一个是不同的会员卡我们希望背景色显示不同。我们先处理一下这两个问题 1 显示会员卡类型 在列表上直接显示会员卡类型,目前显示的是数字,这个是因为枚举类型导致的。枚举类型在数…...
学习 Python 之 Pygame 开发坦克大战(五)
学习 Python 之 Pygame 开发坦克大战(五)坦克大战完善地图1. 创建砖墙2. 给砖墙增加子弹击中的碰撞效果3. 给砖墙添加坦克不能通过的碰撞效果4. 添加石墙5. 添加玩家基地6. 最终效果坦克大战完善地图 我的素材放到了百度网盘里,里面还有原版…...
【ROS】Windows系统安装ROS体验
大家平时玩ROS都是在Ubuntu系统上,那Windows系统可以安装吗,答案是:可以的!Windows为了发展自家的物联网生态,已经在Windows系统支持ROS了。 文章目录1.安装VS 20172.安装Chocolatey & Git3.安装ROS4.运行ROS例程1…...
第1讲-初步认识数据库系统(测试题总结)
一、测试题 数据库系统 包含 数据库管理系统 详细版: 数据库管理系统DBMS是数据管理软件,在用户和操作系统之间。 数据库系统DBS由数据库,数据库管理系统(及其应用开发工具)、应用程序和数据库管理员DBA组成的存储、管…...
进程-操作系统结构
进程-操作系统结构 中文仅本人理解,有错误请联系我。 操作系统为不同方面服务,有不同的设计角度。 为用户: 使用 为程序员:创造 程序员需要关注的就是system call接口的调度 file systems:ntfs,ext4 commu…...
【网络原理6】数据链路层协议——以太网
数据链路层负责的是相邻两个网络节点之间的数据以帧为单位进行传输。 具体关于数据链路层的介绍,已经在这一篇文章当中提到了。 初识网络:IP、端口、网络协议、TCP-IP五层模型_革凡成圣211的博客-CSDN博客TCP/IP五层协议详解https://blog.csdn.net/weix…...
组合数学原理与例题
目录 一、前言 二、计数原理 1、加法原理 2、分割立方体(lanqiaoOJ题号1620) 3、乘法原理 4、挑选子串(lanqiaoOJ题号1621) 5、糊涂人寄信(lanqiaoOJ题号1622) 6、战斗吧N皇后(lanqiaoO…...
【机器学习 深度学习】通俗讲解集成学习算法
目录:集成学习一、机器学习中的集成学习1.1 定义1.2 分类器(Classifier)1.2.1 决策树分类器1.2.2 朴素贝叶斯分类器1.2.3 AdaBoost算法1.2.4 支持向量机1.2.5 K近邻算法1.3 集成学习方法1.3.1 自助聚合(Bagging)1.3.2 提升法(Boosting)1.3.2.1 自适应adaboost1.3.3 …...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
