/proc/sys/vm/ 文档¶
内核版本 2.6.29
版权 (c) 1998, 1999, Rik van Riel <riel@nl.linux.org>
版权 (c) 2008 Peter W. Morreale <pmorreale@novell.com>
有关一般信息和法律说明,请查看 /proc/sys 文档。
此文件包含 /proc/sys/vm 中 sysctl 文件的文档,并且对 Linux 内核版本 2.6.29 有效。
此目录中的文件可用于调整 Linux 内核的虚拟内存 (VM) 子系统的操作以及将脏数据写回磁盘的操作。
这些文件中的大多数的默认值和初始化例程可以在 mm/swap.c 中找到。
目前,这些文件位于 /proc/sys/vm 中
admin_reserve_kbytes
compact_memory
compaction_proactiveness
compact_unevictable_allowed
dirty_background_bytes
dirty_background_ratio
dirty_bytes
dirty_expire_centisecs
dirty_ratio
dirtytime_expire_seconds
dirty_writeback_centisecs
drop_caches
enable_soft_offline
extfrag_threshold
highmem_is_dirtyable
hugetlb_shm_group
laptop_mode
legacy_va_layout
lowmem_reserve_ratio
max_map_count
mem_profiling (仅当 CONFIG_MEM_ALLOC_PROFILING=y 时)
memory_failure_early_kill
memory_failure_recovery
min_free_kbytes
min_slab_ratio
min_unmapped_ratio
mmap_min_addr
mmap_rnd_bits
mmap_rnd_compat_bits
nr_hugepages
nr_hugepages_mempolicy
nr_overcommit_hugepages
nr_trim_pages (仅当 CONFIG_MMU=n 时)
numa_zonelist_order
oom_dump_tasks
oom_kill_allocating_task
overcommit_kbytes
overcommit_memory
overcommit_ratio
page-cluster
page_lock_unfairness
panic_on_oom
percpu_pagelist_high_fraction
stat_interval
stat_refresh
numa_stat
swappiness
unprivileged_userfaultfd
user_reserve_kbytes
vfs_cache_pressure
watermark_boost_factor
watermark_scale_factor
zone_reclaim_mode
admin_reserve_kbytes¶
系统中应为具有 cap_sys_admin 功能的用户保留的空闲内存量。
admin_reserve_kbytes 默认为 min(3% 的空闲页,8MB)
在默认的过度提交 “猜测” 模式下,这应该足以让管理员登录并在必要时终止进程。
在 “从不” 进行过度提交下运行的系统应增加此值,以考虑用于恢复的程序的完整虚拟内存大小。否则,root 用户可能无法登录以恢复系统。
如何计算最小有用的保留量?
sshd 或 login + bash (或其他一些 shell) + top (或 ps、kill 等)
对于过度提交 “猜测”,我们可以对常驻集大小 (RSS) 求和。在 x86_64 上,这大约是 8MB。
对于过度提交 “从不”,我们可以取其虚拟大小 (VSZ) 的最大值,然后加上其 RSS 的总和。在 x86_64 上,这大约是 128MB。
每当应用程序请求内存时,更改此值就会生效。
compact_memory¶
仅当设置了 CONFIG_COMPACTION 时才可用。当向文件写入 1 时,将压缩所有区域,以便在可能的情况下以连续块的形式提供空闲内存。例如,这对于分配大页很重要,尽管进程也会根据需要直接压缩内存。
compaction_proactiveness¶
此可调参数的值范围为 [0, 100],默认值为 20。此可调参数确定在后台进行压缩的积极程度。将非零值写入此可调参数将立即触发主动压缩。将其设置为 0 将禁用主动压缩。
请注意,压缩具有非平凡的系统范围影响,因为属于不同进程的页面会被移动,这也可能导致毫无戒心的应用程序的延迟峰值。如果内核检测到主动压缩无效,则内核会采用各种启发式方法来避免浪费 CPU 周期。
设置极端值 (如 100) 时要小心,因为这可能会导致过多的后台压缩活动。
compact_unevictable_allowed¶
仅当设置了 CONFIG_COMPACTION 时才可用。当设置为 1 时,压缩允许检查不可清除的 lru (锁定的页面) 以查找要压缩的页面。这应该用于次要页面错误的停顿对于大型连续空闲内存是可接受的折衷方案的系统。设置为 0 以防止压缩移动不可清除的页面。默认值为 1。在 CONFIG_PREEMPT_RT 上,默认值为 0,以避免由于压缩而导致的页面错误,这会阻止任务在错误解决之前变为活动状态。
dirty_background_bytes¶
包含后台内核刷新线程将开始写回的脏内存量。
- 注意
dirty_background_bytes 是 dirty_background_ratio 的对应项。一次只能指定其中一个。当写入一个 sysctl 时,它会立即被考虑用于评估脏内存限制,而另一个在读取时显示为 0。
dirty_background_ratio¶
包含一个百分比,即包含空闲页面和可回收页面的可用内存总量的百分比,其中后台内核刷新线程将开始写出脏数据的页面数。
可用内存总量不等于系统内存总量。
dirty_bytes¶
包含一个脏内存量,当产生磁盘写入的进程达到该量时,它本身将开始写回。
注意:dirty_bytes 是 dirty_ratio 的对应项。一次只能指定其中一个。当写入一个 sysctl 时,它会立即被考虑用于评估脏内存限制,而另一个在读取时显示为 0。
注意:dirty_bytes 允许的最小值为两个页面 (以字节为单位);任何低于此限制的值都将被忽略,并且将保留旧的配置。
dirty_expire_centisecs¶
此可调参数用于定义脏数据何时足够旧,适合由内核刷新线程写出。它以百分之一秒为单位表示。在内存中保持脏状态的时间长于此间隔的数据将在下次刷新线程唤醒时写出。
dirty_ratio¶
包含一个百分比,即包含空闲页面和可回收页面的可用内存总量的百分比,其中产生磁盘写入的进程本身将开始写出脏数据的页面数。
可用内存总量不等于系统内存总量。
dirtytime_expire_seconds¶
当一个延迟写入的 inode 的页面不断被修改时,带有更新时间戳的 inode 将永远没有机会被写回。并且,如果文件系统中发生的唯一事情是由 atime 更新导致的脏时间 inode,则会调度一个工作线程来确保该 inode 最终被推送到磁盘。此可调参数用于定义脏 inode 何时足够旧,可以被内核刷新线程进行回写。它还用作唤醒 dirtytime_writeback 线程的间隔。
dirty_writeback_centisecs¶
内核刷新线程会定期唤醒并将旧的数据写回磁盘。此可调参数表示这些唤醒之间的间隔,单位为百分之一秒。
将其设置为零会完全禁用定期回写。
drop_caches¶
写入此文件将导致内核删除干净的缓存,以及可回收的 slab 对象(如目录项和 inode)。删除后,它们的内存将变为可用。
释放页面缓存
echo 1 > /proc/sys/vm/drop_caches
释放可回收的 slab 对象(包括目录项和 inode)
echo 2 > /proc/sys/vm/drop_caches
释放 slab 对象和页面缓存
echo 3 > /proc/sys/vm/drop_caches
这是一个非破坏性操作,不会释放任何脏对象。要增加此操作释放的对象数量,用户可以在写入 /proc/sys/vm/drop_caches 之前运行 sync。这将最大限度地减少系统上的脏对象数量,并创建更多可以删除的候选对象。
此文件不是控制各种内核缓存(inode、目录项、页面缓存等)增长的手段。当系统其他地方需要内存时,这些对象会自动被内核回收。
使用此文件可能会导致性能问题。由于它会丢弃缓存的对象,因此重建丢弃的对象可能需要大量的 I/O 和 CPU 资源,尤其是在它们被大量使用的情况下。因此,不建议在测试或调试环境之外使用。
当使用此文件时,您可能会在内核日志中看到信息性消息
cat (1234): drop_caches: 3
这些只是信息性的。它们并不意味着您的系统有任何问题。要禁用它们,请将 4(位 2)回显到 drop_caches 中。
enable_soft_offline¶
可纠正的内存错误在服务器上很常见。软离线是内核针对具有(过度)纠正内存错误的内存页面的解决方案。
对于不同类型的页面,软离线具有不同的行为/成本。
对于原始错误页面,软离线会将正在使用的页面的内容迁移到新的原始页面。
对于属于透明大页面的页面,软离线会将透明大页面拆分为原始页面,然后仅迁移原始错误页面。因此,用户透明地由少一个大页面支持,从而影响内存访问性能。
对于属于 HugeTLB 大页面的页面,软离线首先迁移整个 HugeTLB 大页面,在此期间,将消耗一个空闲大页面作为迁移目标。然后,原始大页面被分解为原始页面,而无需补偿,从而使 HugeTLB 池的容量减少 1。
用户需要在可靠性(远离脆弱的物理内存)与透明和 HugeTLB 情况下的性能/容量影响之间做出选择。
对于所有架构,enable_soft_offline 控制是否软离线内存页面。当设置为 1 时,内核会在认为需要时尝试软离线页面。当设置为 0 时,内核会向软离线页面的请求返回 EOPNOTSUPP。其默认值为 1。
值得一提的是,将 enable_soft_offline 设置为 0 后,将不会执行以下软离线页面的请求
来自 RAS 可纠正错误收集器的软离线页面请求。
在 ARM 上,来自 GHES 驱动程序的软离线页面请求。
在 PARISC 上,来自页面取消分配表的软离线页面请求。
extfrag_threshold¶
此参数影响内核是否会压缩内存或直接回收以满足高阶分配。debugfs 中的 extfrag/extfrag_index 文件显示了系统中每个区域中每个阶的碎片索引。趋向于 0 的值表示由于缺乏内存分配将失败,趋向于 1000 的值表示失败是由于碎片造成的,-1 表示只要满足水位线,分配就会成功。
如果碎片索引 <= extfrag_threshold,则内核不会在区域中压缩内存。默认值为 500。
highmem_is_dirtyable¶
仅适用于启用 CONFIG_HIGHMEM 的系统(32 位系统)。
此参数控制高内存是否被视为脏写入器节流。默认情况下不是这种情况,这意味着只有内核直接可见/可用的内存量才能被修改。因此,在具有大量内存且低内存基本耗尽的系统上,写入器可能会过早地被节流,并且流式写入可能会变得非常缓慢。
将值更改为非零值将允许修改更多内存,从而允许写入器写入更多数据,从而可以更有效地刷新到存储。请注意,这也带来了过早的 OOM 杀手的风险,因为某些写入器(例如,直接块设备写入)只能使用低内存,并且它们可以在没有任何节流的情况下用脏数据填充它。
hugetlb_shm_group¶
hugetlb_shm_group 包含允许使用 hugetlb 页面创建 SysV 共享内存段的组 ID。
laptop_mode¶
laptop_mode 是一个控制“笔记本电脑模式”的旋钮。此旋钮控制的所有内容都在 如何使用笔记本电脑模式节省电池电量 中讨论。
legacy_va_layout¶
如果非零,则此 sysctl 会禁用新的 32 位 mmap 布局 - 内核将对所有进程使用旧版 (2.4) 布局。
lowmem_reserve_ratio¶
对于高内存机器上的一些特殊工作负载,内核允许从“低内存”区域分配进程内存是危险的。这是因为该内存随后可以通过 mlock() 系统调用或由于交换空间不可用而被锁定。
而在大型高内存机器上,这种缺乏可回收的低内存可能会致命。
因此,Linux 页面分配器有一种机制,可以防止
(同样的论点适用于旧的 16 兆字节 ISA DMA 区域。此机制还将保护该区域免受
lowmem_reserve_ratio 可调参数确定内核在保护这些较低区域时的积极程度。
如果您的机器使用高内存或 ISA DMA,并且您的应用程序正在使用 mlock(),或者您在没有交换的情况下运行,那么您可能应该更改 lowmem_reserve_ratio 设置。
lowmem_reserve_ratio 是一个数组。您可以通过读取此文件来查看它们
% cat /proc/sys/vm/lowmem_reserve_ratio
256 256 32
但是,这些值不是直接使用的。内核根据它们计算每个区域的保护页数。这些显示为 /proc/zoneinfo 中保护页面的数组,如下所示。(这是 x86-64 盒子的示例)。每个区域都有一个如下所示的保护页面数组
Node 0, zone DMA
pages free 1355
min 3
low 3
high 4
:
:
numa_other 0
protection: (0, 2004, 2004, 2004)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pagesets
cpu: 0 pcp: 0
:
这些保护被添加到分数中,以判断是否应将此区域用于页面分配或应回收。
在此示例中,如果此 DMA 区域需要普通页面(索引=2),并且水位线[WMARK_HIGH]用于水位线,则内核判断不应使用此区域,因为 pages_free(1355) 小于水位线 + 保护[2](4 + 2004 = 2008)。如果此保护值为 0,则此区域将用于普通页面需求。如果需求是 DMA 区域(索引=0),则使用保护[0] (=0)。
zone[i] 的 protection[j] 由以下表达式计算
(i < j):
zone[i]->protection[j]
= (total sums of managed_pages from zone[i+1] to zone[j] on the node)
/ lowmem_reserve_ratio[i];
(i = j):
(should not be protected. = 0;
(i > j):
(not necessary, but looks 0)
lowmem_reserve_ratio[i] 的默认值为
256
(如果 zone[i] 表示 DMA 或 DMA32 区域)
32
(其他)
如上述表达式,它们是比率的倒数。256 表示 1/256。保护页面的数量大约是节点上较高区域管理的总页面数的“0.39%”。
如果要保护更多页面,则较小的值是有效的。最小值为 1 (1/1 -> 100%)。小于 1 的值将完全禁用页面的保护。
max_map_count:¶
此文件包含进程可能拥有的最大内存映射区域数。内存映射区域用作调用 malloc 的副作用,直接由 mmap、mprotect 和 madvise 使用,以及在加载共享库时使用。
虽然大多数应用程序需要少于一千个映射,但某些程序,特别是 malloc 调试器,可能会消耗大量映射,例如,每个分配最多一两个映射。
默认值为 65530。
mem_profiling¶
启用内存分析(当 CONFIG_MEM_ALLOC_PROFILING=y 时)
1:启用内存分析。
0:禁用内存分析。
启用内存分析会为所有内存分配引入少量的性能开销。
默认值取决于 CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT。
memory_failure_early_kill:¶
控制如何在硬件在后台检测到无法由内核处理的未纠正内存错误(通常是内存模块中的 2 位错误)时杀死进程。在某些情况下(例如页面在磁盘上仍然有有效副本),内核将透明地处理故障,而不会影响任何应用程序。但是,如果没有其他最新的数据副本,它将杀死以防止任何数据损坏传播。
1:只要检测到损坏,就杀死所有映射了损坏且不可重新加载的页面的进程。请注意,这不支持少数类型的页面,例如内核内部分配的数据或交换缓存,但适用于大多数用户页面。
0:仅从所有进程中取消映射损坏的页面,并且仅杀死尝试访问它的进程。
杀死是使用可捕获的 SIGBUS 和 BUS_MCEERR_AO 完成的,因此进程可以根据需要处理它。
这仅在具有高级机器检查处理的架构/平台上处于活动状态,并且取决于硬件功能。
应用程序可以使用 PR_MCE_KILL prctl 单独覆盖此设置
memory_failure_recovery¶
启用内存故障恢复(如果平台支持)
1:尝试恢复。
0:在内存故障时始终panic。
min_free_kbytes¶
用于强制 Linux VM 保留至少一定数量的可用千字节。VM 使用此数字为系统中的每个低内存区域计算水印[WMARK_MIN]值。每个低内存区域都会根据其大小按比例获得一定数量的保留可用页面。
需要一些最少的内存来满足 PF_MEMALLOC 分配;如果将此值设置低于 1024KB,您的系统将会出现微妙的故障,在高负载下容易发生死锁。
如果设置过高,会立即导致机器 OOM。
min_slab_ratio¶
此选项仅在 NUMA 内核上可用。
每个区域中总页面数的百分比。在区域回收(从本地区域回退时会发生)中,如果区域中超过此百分比的页面是可回收的 slab 页面,则会回收 slab。这可以确保即使在很少执行全局回收的 NUMA 系统中,slab 的增长也受到控制。
默认值为 5%。
请注意,slab 回收是按区域/节点触发的。回收 slab 内存的过程目前不是节点特定的,可能不会很快。
min_unmapped_ratio¶
此选项仅在 NUMA 内核上可用。
这是每个区域中总页面数的百分比。只有当超过此百分比的页面处于 zone_reclaim_mode 允许回收的状态时,才会发生区域回收。
如果 zone_reclaim_mode 的值为 4 OR'd,则该百分比与所有文件支持的未映射页面(包括交换缓存页面和 tmpfs 文件)进行比较。否则,仅考虑由普通文件支持的未映射页面,而不考虑 tmpfs 文件和类似文件。
默认值为 1%。
mmap_min_addr¶
此文件指示用户进程将被限制映射的地址空间量。由于内核空指针解除引用错误可能会意外地基于内存中前几页的信息进行操作,因此不应允许用户空间进程写入它们。默认情况下,此值设置为 0,安全模块不会强制执行任何保护。将此值设置为类似 64k 的值将允许绝大多数应用程序正常工作,并为将来潜在的内核错误提供深度防御。
mmap_rnd_bits¶
此值可用于选择用于确定 vma 区域基址的随机偏移量的位数,该区域是由于支持调整地址空间随机化的架构上的 mmap 分配而产生的。此值将受架构支持的最小值和最大值的限制。
此值可以在启动后使用 /proc/sys/vm/mmap_rnd_bits 可调参数进行更改
mmap_rnd_compat_bits¶
此值可用于选择用于确定 vma 区域基址的随机偏移量的位数,该区域是由于在支持调整地址空间随机化的架构上以兼容模式运行的应用程序的 mmap 分配而产生的。此值将受架构支持的最小值和最大值的限制。
此值可以在启动后使用 /proc/sys/vm/mmap_rnd_compat_bits 可调参数进行更改
nr_hugepages¶
更改巨页池的最小大小。
请参阅 HugeTLB 页面
hugetlb_optimize_vmemmap¶
当“struct page”(在 include/linux/mm_types.h 中定义的结构)的大小不是 2 的幂时(不寻常的系统配置可能会导致这种情况),此旋钮不可用。
启用(设置为 1)或禁用(设置为 0)HugeTLB Vmemmap 优化 (HVO)。
启用后,后续从 buddy 分配器分配 HugeTLB 页面的 vmemmap 页面将被优化(每个 2MB HugeTLB 页面 7 页,每个 1GB HugeTLB 页面 4095 页),而已经分配的 HugeTLB 页面将不会被优化。当这些优化的 HugeTLB 页面从 HugeTLB 池释放到 buddy 分配器时,需要再次重新映射表示该范围的 vmemmap 页面,并且需要再次重新分配先前丢弃的 vmemmap 页面。如果您的用例是 HugeTLB 页面是“动态”分配的(例如,从不使用“nr_hugepages”显式分配 HugeTLB 页面,而仅设置“nr_overcommit_hugepages”,那些超额提交的 HugeTLB 页面是“动态”分配的),而不是从 HugeTLB 池中提取,您应该权衡内存节省的好处与在 HugeTLB 池和 buddy 分配器之间分配或释放 HugeTLB 页面的更高开销(比以前慢约 2 倍)。需要注意的另一个行为是,如果系统处于高内存压力下,可能会阻止用户将 HugeTLB 页面从 HugeTLB 池释放到 buddy 分配器,因为 vmemmap 页面的分配可能会失败,如果您的系统遇到这种情况,您必须稍后重试。
禁用后,后续从 buddy 分配器分配 HugeTLB 页面的 vmemmap 页面将不会被优化,这意味着从 buddy 分配器分配时的额外开销将消失,而已经优化的 HugeTLB 页面将不会受到影响。如果您想确保没有优化的 HugeTLB 页面,您可以先将 “nr_hugepages” 设置为 0,然后再禁用此选项。请注意,将 0 写入 nr_hugepages 会使任何“正在使用”的 HugeTLB 页面成为剩余页面。因此,这些剩余页面在不再使用之前仍然会进行优化。您需要等待这些剩余页面释放,直到系统中没有优化的页面为止。
nr_hugepages_mempolicy¶
在特定的一组 NUMA 节点上,在运行时更改巨页池的大小。
请参阅 HugeTLB 页面
nr_overcommit_hugepages¶
更改巨页池的最大大小。最大值为 nr_hugepages + nr_overcommit_hugepages。
请参阅 HugeTLB 页面
nr_trim_pages¶
此选项仅在 NOMMU 内核上可用。
此值调整 2 的幂对齐的 NOMMU mmap 分配的过度页面修剪行为。
值为 0 将完全禁用分配修剪,而值为 1 将积极修剪过多的页面。任何值 >= 1 都充当启动分配修剪的水印。
默认值为 1。
有关更多信息,请参阅 No-MMU 内存映射支持。
numa_zonelist_order¶
此 sysctl 仅适用于 NUMA,并且已弃用。除了节点顺序之外的任何操作都会失败!
“从哪里分配内存”由 zonelists 控制。
(此文档为了简单解释,忽略了 ZONE_HIGHMEM/ZONE_DMA32。您可以将 ZONE_DMA 读取为 ZONE_DMA32...)
在非 NUMA 的情况下,GFP_KERNEL 的 zonelist 的顺序如下。ZONE_NORMAL -> ZONE_DMA 这意味着只有当 ZONE_NORMAL 不可用时,GFP_KERNEL 的内存分配请求才会从 ZONE_DMA 获取内存。
在 NUMA 的情况下,您可以考虑以下 2 种类型的顺序。假设有 2 个节点的 NUMA,以下是节点 (0) 的 GFP_KERNEL 的 zonelist
(A) Node(0) ZONE_NORMAL -> Node(0) ZONE_DMA -> Node(1) ZONE_NORMAL
(B) Node(0) ZONE_NORMAL -> Node(1) ZONE_NORMAL -> Node(0) ZONE_DMA.
类型 (A) 为节点 (0) 上的进程提供最佳的局部性,但 ZONE_DMA 将在 ZONE_NORMAL 耗尽之前使用。这增加了 ZONE_DMA 内存不足 (OOM) 的可能性,因为 ZONE_DMA 往往很小。
类型 (B) 不能提供最佳的局部性,但对于 DMA 区域的 OOM 更加健壮。
类型 (A) 称为“节点”顺序。类型 (B) 是“区域”顺序。
“节点顺序”按节点对 zonelist 进行排序,然后在每个节点内按区域排序。为节点顺序指定“[Nn]ode”
“区域顺序”按区域类型对 zonelist 进行排序,然后在每个区域内按节点排序。为区域顺序指定“[Zz]one”
指定“[Dd]efault”以请求自动配置。
在 32 位上,需要保留 Normal 区域以供内核访问,因此将选择“区域”顺序。
在 64 位上,需要 DMA32/DMA 的设备相对较少,因此将选择“节点”顺序。
除非这给您的系统/应用程序造成问题,否则建议使用默认顺序。
oom_dump_tasks¶
启用系统范围的任务转储(不包括内核线程),以便在内核执行 OOM 终止时生成,并包含诸如 pid、uid、tgid、vm 大小、rss、pgtables_bytes、swapents、oom_score_adj 分数和名称之类的信息。这有助于确定为何调用 OOM 终止,以识别导致此问题的恶意任务,并确定为何 OOM 终止器选择终止它所终止的任务。
如果此值设置为零,则此信息将被抑制。在具有数千个任务的非常大的系统中,为每个任务转储内存状态信息可能不可行。当可能不需要此信息时,不应强制此类系统在 OOM 条件下产生性能损失。
如果此值设置为非零值,则每当 OOM 终止器实际终止占用大量内存的任务时,都会显示此信息。
默认值为 1(启用)。
oom_kill_allocating_task¶
在内存不足的情况下,启用或禁用终止触发 OOM 的任务。
如果此值设置为零,则 OOM 终止器将扫描整个任务列表,并根据启发式方法选择要终止的任务。这通常会选择一个恶意的内存占用任务,该任务在终止时会释放大量内存。
如果此值设置为非零值,则 OOM 终止器只会终止触发内存不足情况的任务。这避免了昂贵的任务列表扫描。
如果选择了 panic_on_oom,则它优先于 oom_kill_allocating_task 中使用的任何值。
默认值为 0。
overcommit_kbytes¶
当 overcommit_memory 设置为 2 时,提交的地址空间不允许超过交换空间加上此数量的物理 RAM。请参见下文。
注意:overcommit_kbytes 是 overcommit_ratio 的对应项。两者只能同时指定一个。设置其中一个会禁用另一个(读取时会显示为 0)。
overcommit_memory¶
此值包含一个启用内存过度提交的标志。
当此标志为 0 时,内核会将用户空间内存请求大小与总内存加交换空间进行比较,并拒绝明显的过度提交。
当此标志为 1 时,内核会假装总是有足够的内存,直到内存实际耗尽。
当此标志为 2 时,内核使用“从不过度提交”策略,该策略试图防止任何内存过度提交。请注意,user_reserve_kbytes 会影响此策略。
此功能非常有用,因为有很多程序会 malloc() 大量的内存“以防万一”,但实际上并没有使用太多。
默认值为 0。
有关更多信息,请参阅 过度提交记账 和 mm/util.c::__vm_enough_memory()。
overcommit_ratio¶
当 overcommit_memory 设置为 2 时,已提交的地址空间不允许超过交换空间加上物理 RAM 的此百分比。请参阅上文。
page-cluster¶
page-cluster 控制单次尝试从交换空间读取的连续页面的数量上限。这是页面缓存预读的交换空间对应项。提到的连续性不是指虚拟/物理地址,而是指交换空间上的连续性 - 这意味着它们是一起换出的。
这是一个对数值 - 设置为 0 表示“1 页”,设置为 1 表示“2 页”,设置为 2 表示“4 页”,依此类推。设置为 0 将完全禁用交换空间预读。
默认值为 3(一次 8 页)。如果你的工作负载是交换密集型的,那么将其调整为不同的值可能会有一些小的好处。
较低的值意味着初始错误延迟较低,但同时,如果后续错误是连续页面预读的一部分,则后续错误会产生额外的错误和 I/O 延迟。
page_lock_unfairness¶
此值确定页面锁可以从等待者手中被抢夺的次数。在锁被抢夺此文件中指定的次数(默认为 5)后,将应用“公平锁交接”语义,并且只有在可以获取锁时才会唤醒等待者。
panic_on_oom¶
这启用或禁用内存不足时 panic 的功能。
如果设置为 0,内核会杀死一些称为 oom_killer 的恶意进程。通常,oom_killer 可以杀死恶意进程,系统会幸存下来。
如果设置为 1,则当发生内存不足时,内核会 panic。但是,如果进程通过 mempolicy/cpusets 限制使用节点,并且这些节点变为内存耗尽状态,则可能会有一个进程被 oom-killer 杀死。在这种情况下不会发生 panic。因为其他节点的内存可能是空闲的。这意味着系统总体状态可能还不是致命的。
如果设置为 2,则内核会强制 panic,即使在上述情况下也是如此。即使 oom 发生在内存 cgroup 下,整个系统也会 panic。
默认值为 0。
1 和 2 用于集群的故障转移。请根据你的故障转移策略选择其中一个。
panic_on_oom=2+kdump 为你提供了一个非常强大的工具来调查 oom 发生的原因。你可以获得快照。
percpu_pagelist_high_fraction¶
这是每个区域中可以存储到每 CPU 页面列表的页面比例。这是一个上限,它会根据在线 CPU 的数量进行划分。此值的最小值为 8,这意味着我们不允许每个区域中超过 1/8 的页面存储在每 CPU 页面列表上。此条目仅更改热每 CPU 页面列表的值。用户可以指定一个类似于 100 的数字,以在每 CPU 列表之间分配每个区域的 1/100。
每个每 CPU 页面列表的批处理值保持不变,无论高比例值是多少,因此分配延迟不受影响。
初始值为 0。内核使用此值基于区域的低水位线和本地在线 CPU 的数量来设置高 pcp->high 标记。如果用户将“0”写入此 sysctl,它将恢复为默认行为。
stat_interval¶
更新虚拟机统计信息的时间间隔。默认为 1 秒。
stat_refresh¶
任何读取或写入(仅限 root)都会将所有每 CPU 虚拟机统计信息刷新到其全局总数中,以便在测试时提供更准确的报告,例如 cat /proc/sys/vm/stat_refresh /proc/meminfo
作为副作用,它还会检查负总数(在其他地方报告为 0),如果发现任何负总数,则会“失败”并返回 EINVAL,并在 dmesg 中发出警告。(在撰写本文时,已知一些统计信息有时会出现负数,但没有不良影响:这些统计信息上的错误和警告被抑制。)
numa_stat¶
此接口允许运行时配置 numa 统计信息。
当页面分配性能成为瓶颈,并且你可以容忍一些可能的工具损坏和降低的 numa 计数器精度时,你可以执行以下操作:
echo 0 > /proc/sys/vm/numa_stat
当页面分配性能不是瓶颈,并且你希望所有工具都工作时,你可以执行以下操作:
echo 1 > /proc/sys/vm/numa_stat
swappiness¶
此控件用于定义交换和文件系统分页的大致相对 I/O 开销,取值范围为 0 到 200。当为 100 时,虚拟机假设 I/O 开销相等,因此会平等地对页面缓存和交换支持的页面施加内存压力;较低的值表示交换 I/O 更昂贵,较高的值表示更便宜。
请记住,在内存压力下,文件系统 I/O 模式往往比交换的随机 I/O 更高效。最佳值需要通过实验确定,并且还会依赖于工作负载。
默认值为 60。
对于内存交换,例如 zram 或 zswap,以及在比文件系统更快的设备上进行交换的混合设置,可以考虑使用大于 100 的值。例如,如果针对交换设备的随机 I/O 平均比文件系统 I/O 快 2 倍,则交换性应为 133 (x + 2x = 200, 2x = 133.33)。
当为 0 时,内核不会启动交换,直到空闲页面和文件支持页面的数量小于区域中的高水位线。
unprivileged_userfaultfd¶
此标志控制非特权用户可以使用 userfaultfd 系统调用的模式。将其设置为 0 以限制非特权用户仅在用户模式下处理页面错误。在这种情况下,没有 SYS_CAP_PTRACE 的用户必须传递 UFFD_USER_MODE_ONLY 才能使 userfaultfd 成功。禁止使用 userfaultfd 处理来自内核模式的错误可能会使某些漏洞更难利用。
将其设置为 1 以允许非特权用户不受任何限制地使用 userfaultfd 系统调用。
默认值为 0。
控制 userfaultfd 权限的另一种方法是使用 /dev/userfaultfd 而不是 userfaultfd(2)。请参阅 Userfaultfd。
user_reserve_kbytes¶
当 overcommit_memory 设置为 2(“从不过度提交”模式)时,保留 min(当前进程大小的 3%,user_reserve_kbytes)的空闲内存。这旨在防止用户启动一个占用大量内存的进程,导致他们无法恢复(杀死占用内存的进程)。
user_reserve_kbytes 默认为 min(当前进程大小的 3%,128MB)。
如果将其减少到零,则将允许用户使用单个进程分配所有空闲内存,减去 admin_reserve_kbytes。任何后续尝试执行命令都将导致“fork:无法分配内存”。
每当应用程序请求内存时,更改此值就会生效。
vfs_cache_pressure¶
此百分比值控制内核回收用于缓存目录和 inode 对象的内存的倾向。
在 vfs_cache_pressure=100 的默认值下,内核将尝试以相对于页面缓存和交换缓存回收的“公平”速率回收目录项和 inode。降低 vfs_cache_pressure 会导致内核更倾向于保留目录项和 inode 缓存。当 vfs_cache_pressure=0 时,内核永远不会因为内存压力而回收目录项和 inode,这很容易导致内存不足的情况。将 vfs_cache_pressure 提高到 100 以上会导致内核更倾向于回收目录项和 inode。
将 vfs_cache_pressure 大幅提高到 100 以上可能会对性能产生负面影响。回收代码需要获取各种锁来查找可释放的目录和 inode 对象。当 vfs_cache_pressure=1000 时,它将查找比现有数量多十倍的可释放对象。
watermark_boost_factor¶
此因素控制当内存碎片化时的回收级别。它定义了如果不同移动性的页面在页面块中混合,则将回收的区域高水位线的百分比。其目的是为了减少未来压缩的工作量,并提高未来高阶分配(例如 SLUB 分配、THP 和 hugetlbfs 页面)的成功率。
为了使其相对于 watermark_scale_factor 参数有意义,单位为 10,000 的分数。默认值 15,000 表示,如果页面块因碎片化而混合,则将回收高达高水位线的 150%。回收级别由最近发生的碎片事件的数量确定。如果此值小于页面块,则将回收页面块的页面(例如,在 64 位 x86 上为 2MB)。提升因子为 0 将禁用此功能。
watermark_scale_factor¶
此因子控制 kswapd 的积极性。它定义了在 kswapd 被唤醒之前节点/系统中剩余的内存量,以及在 kswapd 返回睡眠状态之前需要释放的内存量。
单位为 10,000 的分数。默认值 10 表示水位线之间的距离是节点/系统中可用内存的 0.1%。最大值为 3000,即内存的 30%。
线程进入直接回收(allocstall)或 kswapd 过早进入睡眠状态(kswapd_low_wmark_hit_quickly)的高频率可能表明 kswapd 为延迟原因维护的空闲页面数量对于系统中发生的分配突发来说太小了。然后,可以使用此旋钮相应地调整 kswapd 的积极性。
zone_reclaim_mode¶
zone_reclaim_mode 允许用户设置在区域内存耗尽时回收内存的或多或少激进的方法。如果设置为 0,则不会发生区域回收。分配将从系统中的其他区域/节点满足。
这是值的按位或:
1 |
启用区域回收 |
2 |
区域回收写出脏页面 |
4 |
区域回收交换页面 |
zone_reclaim_mode 默认是禁用的。对于文件服务器或受益于数据缓存的工作负载,应保持禁用 zone_reclaim_mode,因为缓存效果可能比数据局部性更重要。
如果已知工作负载是分区的,每个分区都适合一个 NUMA 节点内,并且访问远程内存会导致可衡量的性能下降,请考虑启用一个或多个 zone_reclaim 模式位。页面分配器在分配异地页面之前会采取额外的操作。
允许区域回收写出页面可以阻止正在写入大量数据的进程污染其他节点上的页面。如果一个区域被填满,区域回收会写出脏页,从而有效地节流该进程。这可能会降低单个进程的性能,因为它不能再使用所有系统内存来缓冲传出的写入,但它会保留其他节点上的内存,以便在其他节点上运行的其他进程的性能不会受到影响。
允许常规交换实际上将分配限制在本地节点,除非被内存策略或 cpuset 配置显式覆盖。