blob: e19b5143aedb7b64610b4ec4da08cf27ee4c7135 [file] [log] [blame]
<html devsite><head>
<meta name="book_path" value="/_book.yaml"/>
<meta name="project_path" value="/_project.yaml"/>
</head>
<body>
<!--
Copyright 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<h1 id="lmkd_in_userspace" class="page-title">用户空间中的 LMKD</h1>
<p>本文档介绍了 Android 9 中新增的用户空间 lowmemorykiller 守护进程 (<code>lmkd</code>) 功能及其配置方法。</p>
<p>过去,Android 使用内核中的 lowmemorykiller 驱动程序来缓解内存压力(通过终止非必需进程)。此机制非常严格,具体取决于硬编码值。此外,从内核版本 4.12 开始,lowmemorykiller 驱动程序会从上游内核中排除。</p>
<p>用户空间 <code>lmkd</code> 进程可实现相同的功能,但它是通过现有的内核机制来检测和估测内存压力。该进程使用内核生成的 vmpressure 事件来获取关于内存压力级别的通知。此外,它还可以使用内存 cgroup 功能来限制分配给相应进程的内存资源(根据每个进程的重要性)。</p>
<h1 id="how_to_switch_to_userspace_lmkd" class="page-title">如何改用用户空间 lmkd</h1>
<p>从 Android 9 开始,用户空间 <code>lmkd</code> 会在未检测到内核 lowmemorykiller 驱动程序时激活。请注意,用户空间 <code>lmkd</code> 要求内核支持内存 cgroup。因此,要改用用户空间 <code>lmkd</code>,您应使用以下配置设置编译内核:</p>
<pre class="prettyprint"><code>CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
</code></pre>
<h1 id="lmkd_kill_strategies" class="page-title">lmkd 终止策略</h1>
<p><code>lmkd</code> 支持基于以下各项的新终止策略:vmpressure 事件、其严重性和其他提示(如交换利用率),以及旧模式(在该模式下,<code>lmkd</code> 会像内核 lowmemorykiller 驱动程序一样做出终止决策)。</p>
<p>内存不足的设备和高性能设备的新终止策略有所不同。对于内存不足的设备,一般情况下,系统会选择承受较大的内存压力;对于高性能设备,如果存在内存压力,则属于异常情况,应及时修复,以免影响整体性能。<code>ro.config.low_ram</code> 属性允许选择其中一种模式。有关如何设置此属性的说明,请参阅<a href="/devices/tech/perf/low-ram">低内存配置</a></p>
<p>在旧模式下,<code>lmkd</code> 终止决策是基于可用内存和文件缓存阈值做出的。您可以将 <code>ro.lmk.use_minfree_levels</code> 属性设置为 <code>true</code>,从而启用此模式。</p>
<h1 id="configuring_lmkd_for_specific_device" class="page-title">为特定设备配置 lmkd</h1>
<p>使用以下属性配置 <code>lmkd</code></p>
<table>
<tbody><tr>
<th>属性</th>
<th>使用情况</th>
<th>默认值</th>
</tr>
<tr>
<td><code>ro.config.low_ram</code>
</td>
<td>在内存不足的设备和高性能设备之间进行选择。
</td>
<td><code>false</code>
</td>
</tr>
<tr>
<td><code>ro.lmk.use_minfree_levels</code>
</td>
<td>使用可用内存和文件缓存阈值来决定何时终止。此模式与内核 lowmemorykiller 驱动程序之前的工作原理相同。
</td>
<td><code>false</code>
</td>
</tr>
<tr>
<td><code>ro.lmk.low</code>
</td>
<td>可在低 vmpressure 级别下被终止的进程的最低 oom_adj 得分。
</td>
<td><code>1001</code><br />(已停用)</td>
</tr>
<tr>
<td><code>ro.lmk.medium</code>
</td>
<td>可在中等 vmpressure 级别下被终止的进程的最低 oom_adj 得分。
</td>
<td><code>800</code><br />(已缓存或非必需服务)</td>
</tr>
<tr>
<td><code>ro.lmk.critical</code>
</td>
<td>可在临界 vmpressure 级别下被终止的进程的最低 oom_adj 得分。
</td>
<td><code>0</code><br />(任何进程)</td>
</tr>
<tr>
<td><code>ro.lmk.critical_upgrade</code>
</td>
<td>能够升级到临界级别。
</td>
<td><code>false</code>
</td>
</tr>
<tr>
<td><code>ro.lmk.upgrade_pressure</code>
</td>
<td>由于系统交换次数过多,将在该级别升级 vmpressure 事件的 mem_pressure 上限。
</td>
<td><code>100</code><br />(已停用)</td>
</tr>
<tr>
<td><code>ro.lmk.downgrade_pressure</code>
</td>
<td>由于仍有足够的可用内存,将在该级别忽略 vmpressure 事件的 mem_pressure* 下限。
</td>
<td><code>100</code><br />(已停用)</td>
</tr>
<tr>
<td><code>ro.lmk.kill_heaviest_task</code>
</td>
<td>终止符合条件的最重要任务(最佳决策)与任何符合条件的任务(快速决策)。</td>
<td><code>true</code>
</td>
</tr>
<tr>
<td><code>ro.lmk.kill_timeout_ms</code>
</td>
<td>从某次终止后到其他终止完成之前的持续时间(以毫秒为单位)。
</td>
<td><code>0</code><br />(已停用)</td>
</tr>
<tr>
<td><code>ro.lmk.debug</code>
</td>
<td>启用 <code>lmkd</code> 调试日志。
</td>
<td><code>false</code>
</td>
</tr>
</tbody></table>
<p>*注意:*mem_pressure = 内存使用量/RAM_and_swap 使用量(以百分比的形式表示)</p>
<p>以下是设备配置示例:</p>
<pre class="prettyprint"><code>PRODUCT_PROPERTY_OVERRIDES += \
ro.lmk.low=1001 \
ro.lmk.medium=800 \
ro.lmk.critical=0 \
ro.lmk.critical_upgrade=false \
ro.lmk.upgrade_pressure=100 \
ro.lmk.downgrade_pressure=100 \
ro.lmk.kill_heaviest_task=true
</code></pre>
</body></html>