LowMemoryKiller 的使用(安卓lowmemorykiller)

本文介绍安卓系统中的LowMemoryKiller机制,解析如何通过ADB命令查看内存状态及进程优先级,并提供了一个用于批量获取进程优先级的Shell脚本示例。

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

安卓lowmemorykiller

LowMemoryKiller

adb命令:

>adb root
restarting adbd as root

>adb shell cat sys/module/lowmemorykiller/parameters/minfree
18432,23040,27648,32256,55296,80640

>adb shell cat sys/module/lowmemorykiller/parameters/adj
0,100,200,300,900,906

对于这两个文件的理解,其实质上是配合使用的,minfree里面的数字是表示内存剩余大小80640表示80640*4/1024=315M,而adj中的则表示进程对应的优先级;

即:当内存不足低至315M时,系统就会杀掉进程优先级大于906的进程;

如何查看每个进程的优先级呢?

通过命令adb shell ps 或者adb shell ps |findstr 进程pid 的方式,可以查看所有进程\指定进程的pid

在系统目录 /proc/下,会有每个进程的文件夹

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nOpW4WDh-1657608813441)(LowMemoryKiller.assets/image-20220625103730090.png)]

以进程pid=2528为例,

proc/2528 # ls |grep oom
oom_adj (代表进程的优先级, 数值越大,优先级越低,越容易被杀. 取值范围[-16, 15])
oom_score ( lmk策略中没有看到使用的地方,应该是oom才会使用。 要想提高进程优先级,尽量避免自己被杀,那就得提高进程的oom_score_adj)
oom_score_adj (取值范围[-1000, 1001] ,该值就是AMS设置过来的值, 值定义见ProcessList.java )

高版本的内核都不在使用oom_adj,而是用oom_score_adj,oom_score_adj是一个向后兼容。

综上所述,oom_score_adj 对应的之前提到的kill进程的优先级

adb shell cat sys/module/lowmemorykiller/parameters/adj
0,100,200,300,900,906

若要获取所有进程的adj值,可观察proc下文件类型,根据需求,若要杀应用进程,一般只需要查看四位数字的文件夹即可。

考虑到proc下文件系统访问需要root权限(在此我们默认为系统源码级开发),我们可以用shell脚本来执行获取数据。

shell脚本放哪呢? 通过查看系统文件,发现vendor/bin和system/bin下有很多sh文件,于是,我们可以把sh文件放在更容易操作的system/bin目录下

sh文件如何执行呢?我们把sh文件命名为adj.sh. 可以简单的通过adb命令来执行,adb shell adj.sh,作为代码实现执行,可以通过创建rc文件,在rc文件中定义,写系统属性的时候,执行sh。

adj.sh 可参考如下示例,根据需求进行修改

解释如下:

在sdcard下创建临时文件adj_temp_result.txt将开始和结束时间写入文件的开头和结尾,以便查看本次命令执行开始时间和耗时通过执行ls /proc/[0-9]???/oom_score_adj 的方式,获取所有四位id 的oom_score_adj 路径遍历以上路径,输出oom_score_adj 值和路径,每行格式如:-800/proc/1947/oom_score_adj,从整个文件获取列表,每行第一位是oom_score_adj 值,第三位是pid值。echo输出到文件时,单个>清除文件内容,从文件开头写入,>>代表追加内容到文件尾

#!/bin/sh
touch /sdcard/adj_temp_result.txt
current_time=$(date "+%Y-%m-%d %H:%M:%S.sss")
echo $current_time>/sdcard/adj_temp_result.txt
for line in $(ls /proc/[0-9]???/oom_score_adj)
do
 echo $(cat $line)/$line >>/sdcard/adj_temp_result.txt
done
current_time=$(date "+%Y-%m-%d %H:%M:%S.sss")
echo $current_time>>/sdcard/adj_temp_result.txt

rc和sh的使用

Android.mk 中添加

LOCAL_INIT_RC := adj.rc
$(shell cp -f $(LOCAL_PATH)/adj.rc $(PRODUCT_OUT)/system/etc/init/)
$(shell cp -f $(LOCAL_PATH)/adj.sh $(PRODUCT_OUT)/system/bin/)

adj.rc 如下, 设置系统属性vendor.zw.adj=1 时,执行设为root权限的adj.sh

on property:vendor.zw.adj=1
	start adj-sh

#delete log client
service adj-sh /system/bin/adj.sh
        class main
        user root
        group root
        disabled
        oneshot

以上cp命令也可放在增删模块的mk文件中添加

PRODUCT_COPY_FILES +=
packages/apps/xxx/adj.sh:KaTeX parse error: Undefined control sequence: \ at position 37: …EM)/bin/adj.sh \̲ ̲ package…(TARGET_COPY_OUT_SYSTEM)/etc/init/adj.rc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想要offer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值