android oom killer 进程回收机制

转自:http://book.51cto.com/art/201109/291363.htm


10.2.2  Android与Linux的配合

关于内存回收的时机,Android官方文档提出,Activity所占用的内存在一般情况下不会被回收,只有在系统内存不够用的时候才会回收,并且回收时会有一个潜规则。大致情况是前台Activity最后回收,其次是包含前台的Service或者Provider,再次是后台Activity,最后是后台空进程。而这种机制就意味着AmS需要和Linux操作系统有个约定,因为"系统内存是否够用"属于Linux内核的内存管理控制的事情,AmS是无法预知的。

你可能会想,AmS是运行在Java环境中的,当Java进行内存分配时,如果发生Out Of Memory不就知道系统内存低了吗?事实并非如此,这有两个原因:

尽管AmS运行在Java环境里,但是应用程序和AmS运行在两个独立的Java虚拟机中,应用程序申请内存并不会通知AmS,所以AmS无法感知应用程序申请内存的状况,除非每次应用程序申请内存并发生Out Of Memory时通知AmS,但实际却没有。

Java虚拟机运行时都有各自独立的内存空间,应用程序A发生Out Of Memory并不意味着应用程序B也会发生Out Of Memory,很有可能仅仅是A程序用光了自己内存的上限,而系统内存却还是有的。

以上说明,单纯的AmS是无法获知系统内存是否低的。

那么,什么是"系统内存低"或者"系统内存不够用"呢?从Android底层的Linux来讲,由于其并未采用磁盘虚拟内存机制,所以应用程序能够使用的内存大小完全取决于实际物理内存的大小,所以,"内存低"的含义就是实际物理内存已经被用得所剩无几了。而这又是如何与AmS联系到一起的呢?如图10-19所示。

 
图10-19  Android中内存OOM机制示意图

在Android中运行了一个OOM 进程,即Out Of Memory。该进程启动时会首先向Linux内核中把自己注册为一个OOM Killer,即当Linux内核的内存管理模块检测到系统内存低的时候就会通知已经注册的OOM进程,然后这些OOM Killer就可以根据各种规则进行内存释放了,当然也可以什么都不做。

Android中的OOM Killer进程是仅仅适用于Android应用程序的,该进程在运行时,AmS需要把每一个应用程序的oom_adj值告知给Killer。这个值的范围在-16到15,值越低,说明越重要,这个值类似于Linux系统中的进程nice值,只是在标准的Linux中,有其自己的一套Killer机制。

当发生内存低的条件时,Linux内核管理模块通知OOM Killer,Killer则根据AmS所告知的优先级,强制退出优先级低的应用进程。

以上就是Android和Linux关于内存管理的配合,分析完相关代码可知,OOM Killer是一种可选的方案,对于OEM厂商来讲,完全可以不支持OOM,只有在不支持的情况下,Android才会采用之前所声称的"潜规则"优先退出后台的Activity。这个结论很重要,因为在现在主流的Android平台中都包含了OOM Killer模块,这就意味着AmS仅仅是根据应用进程前后台的关系给其分配一个oom_adj值,剩下的就是oom_killer要干的事情了。


<think> 首先,用户的问题是关于“OOM killer enabled”,意思是想了解OOM Killer启用的原因、影响和解决办法。用户提供了三个引用,我需要参考这些内容来构建回答。 回顾引用内容: - 引用[1]:解释了OOM Killer是内核在内存严重不足触发的机制,终止进程释放内存。提到了OOM分数、内核参数、Cgroup限制等。 - 引用[2]:讨论了OOM Killer机制,当一个进程挂掉,可能由于内存不足触发OOM Killer。 - 引用[3]:提到Android系统中有一个OOM进程,作为OOM Killer,并涉及oom_adj值。 用户的查询是具体关于“OOM killer enabled”,这似乎指的是OOM Killer被启用或触发的场景。OOM Killer通常是Linux内核的一部分,总是在运行,但会在特定条件下被触发。 关键点是: - 原因:当系统内存严重不足,内核触发OOM Killer。 - 影响:它会终止进程(通常是占用内存最多的进程),可能导致服务中断、数据丢失等。 - 解决办法:包括调整内核参数、使用Cgroup限制内存、优化应用程序以减少内存使用等。 我的回答需要: - 使用中文回答。 - 结构清晰,分为原因、影响、解决办法等部分。 - 在行内数学表达式用$...$,独立公式用$$...$$(但这里可能不需要数学公式,除非涉及计算)。 - 添加引用标识在段落末尾,如[^1]。 - 生成相关问题。 回答结构: 1. 引入OOM Killer。 2. 解释启用的原因(触发条件)。 3. 描述影响。 4. 提供解决办法。 5. 结尾并生成相关问题。 确保引用正确: - 引用[1]和[2]来自用户提供的引用,我需要基于这些内容,自然地添加引用标识。 生成相关问题: - 在回答末尾,添加"§§相关问题§§",然后列出几个相关的问题,如如何监控OOM事件、如何配置OOM Killer等。 最终回答框架: - 第一部分:介绍OOM Killer和启用的原因。 - 第二部分:影响。 - 第三部分:解决办法。 - 第四部分:相关问题。 </think> ### OOM Killer 启用的原因、影响及解决办法 OOM Killer(Out-Of-Memory Killer)是 Linux 内核中的一个紧急机制,当系统内存严重不足自动触发,其目的是通过终止选定的进程来释放内存,从而防止系统崩溃或卡死。OOM Killer 的启用并非一个独立的“开关”,而是内核在特定条件下自动激活的过程。以下我将从原因、影响及解决办法三个方面详细解释,基于您提供的引用内容。 #### 一、OOM Killer 启用的原因 OOM Killer 被触发的主要原因在于系统内存资源耗尽。具体包括: - **内存严重不足**:当所有可用内存(包括物理内存和交换空间)都被耗尽,内核无法为新进程分配内存或为现有进程扩展内存需求,此 OOM Killer 会被激活以强制释放资源。引用中提到,"系统内存不足导致触发了 Linux 操作系统 OOM killer 机制"[^2]。 - **内核参数配置**:某些内核参数(如 `vm.overcommit_memory`)可能导致内存过度承诺(overcommit),增加 OOM 风险。默认情况下,内核允许进程申请超过实际可用内存的空间,但当实际使用内存不足,便会触发 OOM Killer[^1]。 - **应用程序行为**:应用程序设计不当(如内存泄漏或突发性高内存需求)会导致内存使用激增,超出系统承受能力。例如,一个占用大量内存的进程可能被优先终止[^1]。 - **Android 系统差异**:在 Android 中,OOM Killer 进程专门用于管理应用程序,其启用取决于 `oom_adj` 值(范围 -16 到 15),值越低表示进程越重要,不易被终止。系统根据应用优先级动态调整,当内存不足触发[^3]。 总之,OOM Killer 启用的根本原因是系统内存资源枯竭,无法通过正常回收机制缓解,内核被迫介入以维持系统稳定[^1][^2]。 #### 二、OOM Killer 启用的影响 OOM Killer 的触发虽然保护了系统整体稳定性,但会带来一系列负面影响: - **进程意外终止**:OOM Killer 会基于每个进程OOM 分数(根据内存占用、优先级等计算)选择并终止目标进程。这可能导致关键服务(如数据库或 Web 服务器)突然中断,造成服务不可用或数据丢失。引用描述,"程序运行了一段间,有个进程挂掉了,正常情况下进程不会主动挂掉",这反映了进程被强制终止的后果[^2]。 - **系统性能波动**:内存释放过程中,系统可能经历短暂的性能下降或卡顿,尤其是在高负载环境下。 - **业务中断风险**:在生产环境中,频繁触发 OOM Killer 可能影响服务质量(QoS),降低用户体验或造成经济损失。例如,在 Android 系统中,低优先级的应用更容易被终止,可能导致后台任务失败[^3]。 - **调试困难**:进程被终止后,可能缺乏清晰的日志记录(尽管内核日志会记录 OOM 事件),增加了问题诊断的复杂度[^1]。 影响程度取决于被终止进程的重要性:如果终止的是非关键进程,系统可能快速恢复;但如果涉及核心服务,则可能导致级联故障[^2][^3]。 #### 三、OOM Killer 启用的解决办法 针对 OOM Killer 的触发,解决办法主要从预防和缓解两方面入手,目标是减少内存不足事件的发生频率或控制其破坏性: 1. **优化应用程序**: - 修复内存泄漏:使用工具(如 Valgrind 或 Java Heap Dump)检测并修复代码中的内存泄漏问题。 - 限制内存使用:在应用程序中添加内存使用上限配置,例如在 Java 应用中设置 `-Xmx` 参数来控制堆大小[^2]。 - 合理设计资源分配:避免突发性高内存需求,采用缓存机制或分批处理数据。 2. **配置内核参数**: - 调整 overcommit 设置:修改 `/etc/sysctl.conf` 文件中的参数,例如设置 `vm.overcommit_memory = 2`(禁止过度承诺内存),以减少 OOM 风险。命令示例: ```bash sysctl vm.overcommit_memory=2 ``` - 设置 OOM 分数优先级:通过 `oom_score_adj` 文件(位于 `/proc/<pid>/`)调整进程OOM 分数,降低关键进程被终止的概率。例如,设置值為 -1000(最小值)使进程更难被终止[^1][^3]。 3. **使用资源限制工具**: - **Cgroups(控制组)**:在 Linux 系统中,利用 Cgroups 对进程组内存使用进行硬性限制。例如,通过 `cgroup` 目录配置内存上限(如 `memory.max`),确保单个进程或容器不会耗尽系统内存。这在生产环境中是推荐的做法,能显著降低 OOM 事件频率[^1]。 - **容器化部署**:在 Docker 或 Kubernetes 中,指定容器的内存限制(如 `docker run -m 512m`),超出容器自动重启而非触发全局 OOM Killer。 4. **监控与预警**: - 实监控内存使用:使用工具如 `top`, `free` 或 Prometheus 监控内存占用率,设置阈值告警(如空闲内存低于 10% 触发)。 - 分析 OOM 日志:检查内核日志(`dmesg` 或 `/var/log/kern.log`)获取 OOM 事件的详细信息,识别高风险进程[^1][^2]。 5. **Android 特定策略**(如适用): - 调整 `oom_adj` 值:在 Android 开发中,通过 AmS(Activity Manager Service)设置应用程序的优先级,避免重要应用被终止[^3]。工具如 `procrank` 可帮助分析内存占用。 总之,解决办法的核心是“事前预防为主”,通过资源限制和优化降低 OOM 概率;同,“事后缓解为辅”,确保关键进程不被误杀。如果 OOM Killer 频繁触发,建议优先排查应用程序问题或升级系统内存资源[^1][^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值