android java进程管理(七)之进程状态和adj值

本文详细介绍了Android系统中的进程状态及adj值的作用与重要性判断标准,并解释了不同状态和adj值所代表的意义,有助于理解进程管理和内存回收机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程的状态和adj值用来定义进程的重要性,如何体现这种重要性?我们知道进程是用来运行组件的,所以组件的重要性就相当于进程的重要性,进程状态和adj值需要以组件的状态为核心来理解。

进程状态

android系统定义的进程状态很简单,仅仅是简单描述一下组件的运行信息

状态描述:
1.PROCESS_STATE_NONEXISTENT:进程运行实体还不存在
2.PROCESS_STATE_PERSISTENT:常驻内存进程
3.PROCESS_STATE_PERSISTENT_UI:常驻内存进程并且有UI显示
4.PROCESS_STATE_TOP:顶端进程,包含顶端activity
5.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:系统绑定了本进程的一个Service组件
6.PROCESS_STATE_FOREGROUND_SERVICE:进程正在运行前台Service组件
7.PROCESS_STATE_TOP_SLEEPING:顶端进程,手机处于锁屏状态
8.PROCESS_STATE_IMPORTANT_FOREGROUND:前台重要进程
9.PROCESS_STATE_IMPORTANT_BACKGROUND:后台重要进程
10.PROCESS_STATE_BACKUP:正在执行备份还原的进程
11.PROCESS_STATE_HEAVY_WEIGHT:重量级进程
12.PROCESS_STATE_SERVICE:进程正在运行Service组件
13.PROCESS_STATE_RECEIVER:进程正在运行广播接收器
14.PROCESS_STATE_HOME:home进程
15.PROCESS_STATE_LAST_ACTIVITY:包含上一个显示Activity的进程
16.PROCESS_STATE_CACHED_ACTIVITY:缓存Activity的进程
17.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:这个进程持有16进程组件的客户端
18.PROCESS_STATE_CACHED_EMPTY:空进程

第1个状态不是一个完整的进程,其他的进程状态是值越小越重要,那么大家是不是有点困惑?四大组件中不是Activity最重要吗?为什么15 16 17 的进程比12 13 的进程的重要性要低呢?这里边还有一个运行的概念,运行的一定比不运行的重要,12 13 都是正在运行的Service组件和广播接收器组件,而15 16 17 仅是指存在Activity,所以12 13 的重要性要高,区分一个进程的重要性从下面几个层次来看:

  • 1.是不是常驻内存进程
  • 2.是不是处于运行的状态
  • 3.组件的重要性:Activity>Service>广播接收器

adj值

这个值是给lmk(lowmemorykiller)子系统使用的,lmk是android提供的进程内存管理的子系统,这个系统有点黑,采用直接kill进程的方式回收内存,属于相当暴力的方式,所以对adj的值计算需要小心为妙,否则进程动不动被kill就不好了,android系统定义了如下级别的adj值

adj值描述:
1.NATIVE_ADJ:本地进程的adj值,不受AMS的管理
2.SYSTEM_ADJ:system_server进程的adj值
3.PERSISTENT_PROC_ADJ:常驻内存进程的adj值
4.PERSISTENT_SERVICE_ADJ:这种进程含有一个Service组件,这个组件被系统进程或者常驻内存进程绑定了
5.FOREGROUND_APP_ADJ:前台进程
6.VISIBLE_APP_ADJ:可见进程(进程包含的Activity可见)
7.PERCEPTIBLE_APP_ADJ:用户可感受的进程,什么是可感受?看是一种感受,听也是一种感受,比如后台运行的音乐播放器就是听觉感受,它就属于这类进程
8.BACKUP_APP_ADJ:运行备份还原的进程
9.HEAVY_WEIGHT_APP_ADJ:重量级进程
10.SERVICE_ADJ:含有Service组件的进程
11.HOME_APP_ADJ:home进程
12.PREVIOUS_APP_ADJ:前一个进程
13.SERVICE_B_ADJ:B list Service
14.CACHED_APP_MIN_ADJ:缓存Activity的进程
15.CACHED_APP_MAX_ADJ:缓存Activity的进程
16.UNKNOWN_ADJ:adj值不确定的进程
17.INVALID_ADJ:无效的adj

以上是目前android系统定义的adj值,每一个进程都会赋予一个adj值,越往下进程越不重要,越容易被kill掉
大家有没有发现,adj表面上来看好像没有广播接收器的事呢?其实在第5个(FOREGROUND_APP_ADJ)adj值中都包括了,这个前台进程在这里定义的很广泛,不只是包含top Activity,而且只要进程包含运行Service组件或者正在执行广播接收器,都看作是前台进程,重要性也就很高,adj值的确定的基本准则也适用上面三条:

  • 1.是不是常驻内存进程
  • 2.是不是处于运行的状态
  • 3.组件的重要性:Activity>Service>广播接收器

更新lru容器

更新进程状态和adj值

<think>我们被要求使用ADB命令查看Android进程的实时oom_adj。根据引用[1][2][3]可知,oom_adj是Linux内核中用于调度进程内存释放的机制,越小优先级越高,越不容易被回收。在Android中,我们可以通过查看`/proc/<pid>/oom_score_adj`文件来获取进程的oom_adj(在较新的Android版本中,oom_adj被oom_score_adj替代,但为了兼容,通常仍称为oom_adj)。注意:在Android 8.0及以上,我们通常查看`oom_score_adj`,它替代了旧的`oom_adj`,但概念类似。 步骤: 1. 获取目标进程的PID(进程ID)。 2. 通过PID查看该进程的`oom_score_adj`。 具体命令如下: ### 步骤1:获取进程列表PID 使用以下命令列出所有进程及其PID: ```bash adb shell ps -A ``` 或者,如果想查看特定应用的进程,可以使用包名过滤,例如: ```bash adb shell ps -A | grep com.tencent.mm ``` ### 步骤2:查看指定进程的oom_score_adj 假设我们获取到目标进程的PID为`12345`,则使用以下命令: ```bash adb shell cat /proc/12345/oom_score_adj ``` ### 一步到位的命令 如果想一次性查看所有进程的oom_score_adj,可以使用以下命令: ```bash adb shell ps -A -o PID,NAME | awk '{print $1}' | xargs -I {} sh -c 'echo -n "PID {}: "; cat /proc/{}/oom_score_adj 2>/dev/null' ``` 但是,这个命令在部分Android设备上可能因为缺少awk或xargs而无法运行。因此,更通用的方法是编写一个简单的shell脚本,但通过adb shell执行多行命令较为复杂。 ### 替代方法:使用单个进程查看 我们可以先获取进程列表,然后逐个查看。例如,查看微信(包名com.tencent.mm)相关进程的oom_score_adj: ```bash adb shell "ps -A | grep com.tencent.mm | awk '{print \$2}' | while read pid; do echo \"PID: \$pid, oom_score_adj: \$(cat /proc/\$pid/oom_score_adj 2>/dev/null)\"; done" ``` 注意:在较新的Android版本中,可能需要root权限才能查看其他进程的`/proc/<pid>/oom_score_adj`文件。如果没有root权限,可能只能查看自己应用的进程。 ### 解释 - `oom_score_adj`:取范围是-1000到1000,越小表示进程优先级越高,越不容易被杀死。 - 常见: - 前台应用:0 - 可见应用:100 - 次要服务:200 - 后台应用:300 - 缓存应用:400 - 系统保留:-1000(系统进程) ### 示例输出 假设微信的主进程PID为12345,则命令`adb shell cat /proc/12345/oom_score_adj`的输出可能是: ``` 0 ``` 表示该进程当前是前台进程。 ### 注意事项 1. 部分设备可能因为权限问题无法查看非本用户的进程信息,此时需要root权限。 2. 在Android 8.0及以上,`oom_adj`已经被`oom_score_adj`取代,但两者作用相似,我们查看`oom_score_adj`。 ### 引用说明 根据引用[4]中的例子,他们查看了微信QQ进程的oom_adj,其中微信的push进程显示为0(前台进程)。在Android系统中,通过这种方式可以监控进程的优先级状态。 因此,用户可以通过上述ADB命令查看实时oom_score_adj。 §§相关问题§§ 1. 如何提升Android应用的进程优先级? 2. 在Android中,oom_score_adjoom_adj有什么区别? 3. 没有root权限如何查看应用的oom_score_adj?</think>### 使用 ADB 查看 Android 进程实时 oom_adj Android 系统中,`oom_adj`(Out-Of-Memory Adjustment)决定了进程在内存不足时被系统回收的优先级。数范围从 -17 到 16,**越小表示优先级越高**,越不容易被系统杀死[^1][^2]。 #### 查看步骤: 1. **获取目标进程的 PID** ```bash adb shell ps -A | grep <包名或进程名> ``` 示例(查看微信进程): ```bash adb shell ps -A | grep tencent ``` 2. **查看指定进程的 oom_adj ** ```bash adb shell cat /proc/<PID>/oom_score_adj ``` > **注意**:在 Android 7.0+ 中,`oom_adj` 已被 `oom_score_adj` 替代,但作用相同[^3]。 3. **批量查看所有进程(需要 root)** ```bash adb shell su -c "ps -A -o PID,NAME,COMM | while read pid name comm; do echo \"\$name (\$pid): \$(cat /proc/\$pid/oom_score_adj 2>/dev/null)\"; done" ``` #### 常见 oom_adj 含义: | | 进程类型 | 说明 | |---------|-----------------------|--------------------------| | **-17** | `NATIVE_ADJ` | Native 进程,永久驻留内存 | | **0** | `FOREGROUND_APP_ADJ` | 前台应用进程 | | **1-5** | `VISIBLE_APP_ADJ` | 可见应用进程 | | **6-7** | `PERCEPTIBLE_APP_ADJ` | 可感知进程(如后台音乐) | | **8-15**| `CACHED_APP_MIN_ADJ` | 缓存进程(优先回收) | #### 实际案例(参考引用[4]): ```bash # 微信推送服务进程 adb shell cat /proc/12420/oom_score_adj # 输出:0 (前台进程优先级) # QQ 下载服务进程 adb shell cat /proc/12474/oom_score_adj # 输出:16 (低优先级缓存进程) ``` > **权限说明**: > - 查看系统进程需要 root 权限 > - 普通应用只能查看自身进程的 oom_adj > - Android 8.0+ 对 oom_adj 访问有更严格限制[^3] #### 实用技巧: 1. **实时监控变化**: ```bash adb shell watch -n 1 "cat /proc/<PID>/oom_score_adj" ``` 2. **结合内存状态查看**: ```bash adb shell dumpsys activity processes | grep -E "Proc #|oom_adj" ``` 3. **进程优先级排序**: ```bash adb shell ps -A -o PID,NAME,ADJ --sort=ADJ ``` --- ### 相关问题 1. **如何提升 Android 应用的进程优先级?** `通过修改 oom_adj (需系统权限),或使用前台服务提升优先级[^1][^3]` 2. **oom_adj 进程冻结(freeze)机制有何关联?** `低优先级(高 oom_adj )的进程会优先被冻结或回收` 3. **Android 如何动态调整进程的 oom_adj ?** `系统根据应用状态(前台/后台)自动调整,开发者也可通过特定 API 干预[^3]` [^1]: oom_adj是Linux内核中一个用于调度进程内存释放的机制 [^2]: 进程保活之oom_adj级别查询 [^3]: 通过ProcessList.java中的setOomAdj方法去调整进程的优先级 [^4]: 查下企鹅的三个进程的 oom_adj
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值