Android LowMemoryKiller概述
Agenda
Low memory killer 概述
内核空间LMK
ULMK‐vmpressure
ULMK‐PSI
Low memory killer 概述
lowmemorykiller的作用就是当内存比较紧张的时候去及时杀掉一些对用户来说不那么重要的进程,回收内存,保证手机的正常运行。安卓平台lowmemorykiller机制演进:

内核空间LMK
Kernel LMK相关概念
• /sys/module/lowmemorykiller/parameters/minfree:
18432,23040,27648,32256,55296,80640
数字代表一个内存级别
• /sys/module/lowmemorykiller/parameters/adj:
0,100,200,300,900,906
数字代表一个进程优先级级别
当手机内存低于80640时,就去杀掉优先级906以及以上级别的进程;当内存低于55296时,就去杀掉优先级900以及以上的进程。
• proc/pid/oom_adj:代表当前进程的优先级,这个优先级是kernel中的进程优先级
• /proc/pid/oom_score_adj:上层优先级,跟ProcessList中的优先级对应
Lmkd:在手机中是一个常驻进程,lmkd是在init进程启动的时候启动,根据AMS指示更新进程优先级
内核空间LMK

AMS: ActivityManagerService
Lmkd: userspace lowmemory killer daemon
Lowmemorykiller :The lowmemorykiller driver lets user‐space specify a set of memory thresholds where processes with a range of oom_score_adj values will get killed.

AMS与lmkd的通信
AMS与lmkd通过socket通信
主要分为三种command,每种command代表一种数据控制方式:
LMK_TARGET:更新/sys/module/lowmemorykiller/parameters/中的minfree以及adj
LMK_PROCPRIO:更新指定进程的优先级,也就是oom_score_adj
LMK_PROCREMOVE:移除进程
Lowmemorykiller init
初始化lowmemorykiller,注册shrinker,当空闲内存页面不足时,内核线程kswpd会调用注册的shrink回调函数来回收页面。

lowmem_scan 调用流程
回收内存流程时会被调用,lowmem_scan挂到了register_shrinker里,shrink_slab_node里会scan_objects
调用栈:
• [<c082a824>] (lowmem_scan) from [<c01e0ba4>]
(shrink_slab_node+0x204/0x3d0)
• [<c01e0ba4>] (shrink_slab_node) from [<c01e12b8>]
(shrink_slab+0x70/0xe4)
• [<c01e12b8>] (shrink_slab) from [<c01e3ba8>]
(try_to_free_pages+0x3c0/0x74c)
• [<c01e3ba8>] (try_to_free_pages) from [<c01d9188>]
(__alloc_pages_nodemask+0x578/0x92c)
判断是否需要kill进程
- lowmem_scan首先看看能不能找到oom_score_adj,如果找不到就认为内存充足不杀进程。
- 判断内存是否充足的条件就是other_free和other_file两个都必须同时小于lowmem_minfree中的用户设定值,other_free基本上是free pages,other_file基本上是file pages,两者可以分别看成MemFree和Cached大小

查找被杀进程
遍历所有的进程for_each_process,查找 oom_score_adj要比min_score_adj大且rss最大的进程,通过send_sig(SIGKILL, selected, 0)杀掉。

Issues with lowmemorykiller kernel driver
- Relies on hard‐coded free‐memory limits with no scaling based on the memory pressure
- Vendors often heavily customize the driver to work on their devices, which indicates rigidity of the design. Customizations include listening to vmpressure events, adding additional free‐memory watermarks, and other memory‐pressure hints
- Hooks into slab shrinker API that was not designed for this purpose. Shrinkers are supposed to quickly drop unused caches and exit in order to avoid slowing down the vmscan process. Workload that lowmemorykiller performs includes searching for heavy processes and killing them, which are not quick operations
ULMK ‐VMPRESSURE
1.监听kernel的vmpressure events,由lmkd根据进程adj以及内存level来决定杀哪些进程。
2.SM8250 的kernel版本4.19,为了支持ULMK,kernel增加了PSI framework(Pressure stall information),PSI会记录CPU/memory/IO 的压力信息并通知用户空间。ULMK通过读取这些数据来决定杀哪个进程。

1. AMS 与 Lmkd 通过soket通信,与前面介绍相同
2. Lmkd 与 Memcg通信

a. kernel 会向 lmkd 报告memory pressure event
b. Lmkd 会根据kernel报告的critical memory pressure 或medium memorypressure 杀app
c. 根据进程的adj以及minfree来选择app杀掉
Lmkd 监听vmpressure
vmpressure本身就定义了low, medium, critical三类内存压力状态,LMKD 的初始化流程:
Lmkd::init()
‐> init_mp_common(low,medium,critical)
open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
evctlfd = open(MEMCG_SYSFS_PATH "cgroup.event_control", O_WRONLY | O_CLOEXEC);
write(evctlfd, buf, strlen(buf) + 1)
> memcg_write_event_control
event‐>register_event = vmpressure_register_event;
event‐>register_event(memcg, event‐>eventfd, buf);
Lmkd 如何处理vmpressure
对于 memory pressure 事件,处理函数是 mp_event_common,传递给他的 data 是memory
pressure level
Lmkd::init
‐>init_mp_common
vmpressure_hinfo[level_idx].data = level_idx;
vmpressure_hinfo[level_idx].handler = mp_event_common;
epev.data.ptr = (void *)&vmpressure_hinfo[level_idx];
ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, evfd, &epev);
处理函数入口:mp_event_common
‐>use_minfree_levels
if (other_free < minfree && other_file < minfree)
min_score_adj = lowmem_adj[i];
pages_to_free = lowmem_minfree[lowmem_targets_size ‐ 1] ‐ ((other_free < other_file) ? other_free : other_file);
do_kill:
find_and_kill_processes(min_score_adj, 0);
在未开启use_minfree_levels的情况下,需要结合mp level以及swap 分区空余大小来决定是否
kill app
‐>!use_minfree_levels
if (mi.field.nr_free_pages < low_pressure_mem.max_nr_free_pages) {
pages_to_free = low_pressure_mem.max_nr_free_pages ‐
mi.field.nr_free_pages; }
if (level < VMPRESS_LEVEL_CRITICAL &&
mi.field.free_swap > low_pressure_mem.max_nr_free_pages)
return;
min_score_adj = level_oomadj[level];
find_and_kill_processes(min_score_adj, 0);
Issues with vmpressure for memory pressure detection:
• Reflects current reclaim efficiency rather than memory pressure level
• Difficult to tune because of no direct link between reclaim efficiency
and its effects on user experience
• Tightly coupled with vmscan implementation, changes in vmscan
mechanisms may result in behavior change
• In testing, highly depends on the system memory size and particular
workload
ULMK‐‐PSI
PSI improvements
• More accurate pressure detection compared to vmpressure (2‐10x
fewer false positives)
• Thresholds are configurable making tuning possible
• PSI signals are rate‐limited and userspace can decide how often to
poll after the first signal
• Supports unlimited number of triggers
PSI
PSI将各个任务延迟汇总为资源压力指标,这些指标反映工作负载运行状况和资源利用率方面的问题。
基准productivity:可以在CPU上执行任务的时间。
压力:表示由于资源争用而无法执行任务的时间量。
productivity的概念包括两个部分:workload和CPU。 为了衡量压力对两者的影响,我们定义了两个资源的争用状态:SOME和FULL。
• SOME: Time percentage due to the stalling of a few tasks caused by lack of a specific kind of resource.
• FULL: Time percentage due to the stalling of all tasks caused by lack of a specific kind of resource.

• Psi旨在提供可供用户配置的低延迟的短期压力监测机制。
• 在用户定义的时间窗口内度量延迟高于用户定义的阈值时通知用户。
• 时间窗口和阈值都以usecs表示,可以同时监视具有不同阈值和窗口大小的多个psi资源。
• PSI监测的资源包括:memory,IO以及cpu
PSI如何监控资源压力
• 用户需要注册trigger,当资源压力超过门限值时通过poll()通知
用户。
• Trigger描述的是特定时间窗口内的最大累计停顿时间,例如 任何
500ms窗口内100ms的总停顿时间生成唤醒事件。
• 要注册trigger,用户必须在proc / pressure /下打开psi接口文件,
表示要监视的资源,并写入所需的阈值和时间窗口。例如,将
“some 150000 1000000”写入/ proc / pressure / memory,将为在1
秒时间窗口内测量的部分内存停顿150ms阈值。
• PSI监视器仅在系统进入受监测的psi度量标准的卡顿状态时激活,
并在退出卡顿状态时停用。
注册trigger代码实例

LMKD注册trigger

系统记录memory stall状态
系统通过psi_memstall_enter以及psi_memstall_leave记录memory stall 状态,
在下面几个内存相关的文件将对memstall 状态进行记录
mm/compaction.c
mm/filemap.c, mm/page_alloc.c mm/vmscan.c

Psi 更新trigger

通知事件
psi_fop_poll此函数是用户态发起poll()系统调用后,会有psi此函数对接,检查在此poll之前的时间内是否有事件发生,如果有则设置相应事件signal,如果无则通过poll_wait()让其等待。所以用户每次监听io/mem/cpu的任一文件,都会引发此对接函数的调用,根据已有的trigger判断事件监听情况。

Lmkd 处理PSI通知

References
• https://source.android.com/devices/tech/perf/lmkd
• Android Bootcamp 2018 Low Memory Killer changes
• Qcom document: ULMK and Memcg overview on android Go
• https://blog.csdn.net/u011733869/article/details/78820240
• http://tjtech.me/analyze‐lmk‐kernel.html
• https://lkml.org/lkml/2019/1/10/910
相关文章:
Android LowMemoryKiller概述
Agenda Low memory killer 概述 内核空间LMK ULMK‐vmpressure ULMK‐PSI Low memory killer 概述 lowmemorykiller的作用就是当内存比较紧张的时候去及时杀掉一些对用户来说不那么重要的进程,回收内存,保证手机的正常运行。安卓平台lowmemorykiller机…...
特殊操作流——案例:游戏次数
需求:请求程序实现猜数字小游戏只能试玩三次,如果还想玩,提示:游戏已经结束,想玩请充值(www.itcast.cn) 思路: 写一个游戏类,里面有一个猜数字的小游戏 写一个测试类&am…...
git clone connect to gitlab sign in token弹窗让我输入用户名和密码
系列文章目录 文章目录系列文章目录前言前言 当我使用git bash输入命令:git clone https://gitlab.freedesktop.org/raqm/raqm.git libraqm 弹窗 ASUSLAPTOP-0R30I78P MINGW64 /e/krita-dev $ git clone https://gitlab.freedesktop.org/raqm/raqm.git libraqm C…...
【Blender】如何在Blender中添加HDRI环境贴图
什么是HDRI环境贴图 环境贴图或HDRI贴图是在Blender中照亮3D场景并实现逼真效果的最有效和最快捷的方法之一。 HDRIs本质上是现实世界照明的快照,其中包含高动态范围成像(HDRI)的准确照明细节。HDRI是一个包含亮度信息(从暗…...
前端监控指的是什么?
前端监控分为三个方面: 异常监控(监控前端页面的报错)性能监控(监控页面的性能)用户行为监控(监控用户的行为,计算PV、UV、在线时间等、数据监控即我们常说的埋点 例子1 在后端突然上线了某个需…...
.net core 面试题 2023
文章目录1. 什么是 ASP.net core2. .net 术语3. 托管资源 和 非托管资源4. GC 和 垃圾回收5. .net中所有类的基类6. 如何实现对象的深拷贝7. 依赖注入,为什么使用依赖注入8. IOC容器的注入方法9. ASP.net core 中 服务生命周期10. scoped的 service 可以注入到 sing…...
和ChatGPT关于Swing music的一场对话(上篇)
什么是 Swing Music ? Swing Music 是一款漂亮的自托管音乐播放器,适用于您的本地音频文件。就像一个更酷的 Spotify …但带上你自己的音乐。 第一次在 reddit 上看到 Swing Music,就被其 UI 吸引了 但源码站点的releases 中只有 windows 和 …...
java版工程项目管理系统源码 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单
ava版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示1…...
debian 10 扩展分区容量
debian 10 扩展分区容量1、扩展分区原因2、添加一块磁盘3、命令记录3.1、新增加的磁盘是/dev/sdb3.2、使用磁盘/dev/sdb 创建物理卷3.3、 把物理卷/dev/sdb加入到卷组debian-vg中3.4、查看物理卷、逻辑卷3.5、扩展逻辑卷/tmp3.6、逻辑卷组debian-vg 空余空间被用掉10g 还剩90g可…...
【无功优化】基于改进遗传算法的电力系统无功优化研究【IEEE30节点】(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
LeetCode 218. 天际线问题
城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度,请返回 由这些建筑物形成的 天际线 。 每个建筑物的几何信息由数组 buildings 表示,其中三元组 buildings[i] [lefti, righti, heighti] 表示…...
Logstash:使用自定义正则表达式模式
有时 Logstash Grok 没有我们需要的模式。 幸运的是我们有正则表达式库:Oniguruma。在很多时候,如果 Logstash 所提供的正则表达不能满足我们的需求,我们选用定制自己的表达式。 定义 Logstash 是一种服务器端数据处理管道,可同时…...
常见的一致性问题及解决
什么是一致性 一致性问题主要是因为分布式系统中的多个节点之间可能存在网络延迟、故障等原因导致的。具体而言,分布式系统中的数据一致性问题可以分为以下几种类型: 强一致性:指在任何时间点,所有节点中的数据都是一致的。这种…...
vue下载文件
注意请求时加入:responseType: bloburl:写全了,因为前后端端口号不同downloadImage(imgUrl) {let formData new FormData();formData.append(fileName, this.getFilename(imgUrl)); // 用于后端下载文件的路径axios.post(http://localhost:8…...
人人都是数据分析师-数据分析之数据图表可视化(下)
当前的BI报表、运营同学的汇报报告中数据图表大多为 表格、折线图、柱状图和饼图,但是实际上还有很多具有代表性的可视化图表,因此将对常见的可视化图表进行介绍,希望这些图表可视化方法能够更好的提供数据的可用性。 人人都是数据分析师-数…...
考勤、充电,绑身份,你的人员定位系统就缺它了!
我们做人脸识别智能发卡充电柜是要解决什么问题? (1)工地、港口等场景,人员流动大,管理难 在工地、港口等场景,人员组成通常比较复杂。有来自施工方、客户、各劳务队、各管理层的人员,以及来自…...
RocketMQ水平扩展及负载均衡详解
文章目录 Broker端水平扩展Broker负载均衡commit logProducer负载均衡Consumer负载均衡集群模式广播模式RocketMQ是一个分布式具有高度可扩展性的消息中间件。本文旨在探索在broker端,生产端,以及消费端是如何做到横向扩展以及负载均衡的。 Broker端水平扩展 Broker负载均衡…...
java接口笔记
关键字:interface 定义形式:interface 接口名 { 接口体 } 细节: 1.接口里的方法可以为抽象方法,静态方法,默认方法(default 关键字) 2.接口里的方法只能是public ,可以不用写&a…...
安利安利-向大家推荐一个超级牛的etcd管理工具-EtcdKeeperFyne
etcd介绍 关于etcd的介绍大家可以看下这篇文章 etcd 开源仓库地址:EtcdKeeperFyne EtcdKeeperFyne 今天主要是向大家推荐一款使用起来特别方便的Etcd管理工具 EtcdKeeperFyne,具体运行起来的界面如下: 推荐原因 使用简单安装简单&…...
数字经济系列讲座-数字化平台(商业购物平台)
数字经济系列讲座 文章目录 钱的流向退货成本research questionLiterature review现金流发生在平台内侧平台商业模式转型Modelmodel 假设四种情形标记符利润函数&效用函数&平台效益模型构建利润对比图结论future directions讲座题目 To Adopt or not? The Impacts of…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
