英语

过度提交记账

Linux 内核支持以下过度提交处理模式

0

启发式过度提交处理。明显的地址空间过度提交会被拒绝。用于典型系统。它确保严重的分配失败,同时允许过度提交以减少交换空间的使用。这是默认设置。

1

始终过度提交。适用于某些科学应用程序。经典示例是使用稀疏数组并且仅依赖于几乎完全由零页面组成的虚拟内存的代码。

2

不进行过度提交。系统总的地址空间提交不能超过交换空间 + 可配置的物理 RAM 量(默认为 50%)。根据您使用的数量,在大多数情况下,这意味着进程在访问页面时不会被杀死,而是会在需要时收到内存分配错误。

对于希望保证其内存分配在未来可用的应用程序非常有用,而无需初始化每个页面。

过度提交策略通过 sysctl vm.overcommit_memory 设置。

过度提交量可以通过 vm.overcommit_ratio(百分比)或 vm.overcommit_kbytes(绝对值)设置。只有当 vm.overcommit_memory 设置为 2 时,这些才会生效。

当前过度提交限制和已提交的量可以在 /proc/meminfo 中以 CommitLimit 和 Committed_AS 分别查看。

陷阱

C 语言堆栈增长会进行隐式 mremap。如果您想要绝对的保证并且在边缘附近运行,则必须为所需的的最大大小 mmap 您的堆栈。对于典型的堆栈使用,这无关紧要,但如果您真的非常在意,这是一个极端情况

在模式 2 中,MAP_NORESERVE 标志被忽略。

工作原理

过度提交基于以下规则

对于文件支持的映射
共享或只读 - 0 成本(文件是映射而不是交换空间)
私有可写 - 每个实例的映射大小
对于匿名或 /dev/zero 映射
共享 - 映射大小
私有只读 - 0 成本(但用处不大)
私有可写 - 每个实例的映射大小
附加记账
由 mmap 创建可写副本的页面
从同一池中提取的 shmfs 内存

状态

  • 我们记账 mmap 内存映射

  • 我们记账提交中的 mprotect 更改

  • 我们记账大小中的 mremap 更改

  • 我们记账 brk

  • 我们记账 munmap

  • 我们在 /proc 中报告提交状态

  • 在 fork 上进行记账和检查

  • 在 exec 上审查堆栈处理/构建

  • SHMfs 记账

  • 实施实际的限制执行

待办事项

  • 记账 ptrace 页面(这很困难)