首页/系统/Linux 内核与性能调优速查/vm.max_map_count 内存映射数量上限
sysctl 内核参数72 条

vm.max_map_count 内存映射数量上限

限制单个进程可持有的内存映射区域数(默认 65530);搜索引擎、JVM、游戏服务器等大量 mmap 的应用常需要提高。

max_map_count 是什么

vm.max_map_count 限制单个进程可以持有的内存映射区域(VMA)数量,默认 65530。每个 mmap 调用、共享库加载、文件映射都会占用一个映射区域。搜索引擎类程序依赖 mmap 打开大量索引文件,JVM 的堆与类元数据、部分游戏服务器与科学计算程序也会产生大量映射。达到上限后新的 mmap 会失败并返回 ENOMEM,应用日志里看到的是 Cannot allocate memory,但内存其实还有余量。

基本信息

参数vm.max_map_count
默认值65530(发行版可能调整过,以本机回读为准)
作用对象单进程的内存映射区域数量,不是内存容量
典型报错mmap 失败返回 ENOMEM,应用提示 Cannot allocate memory
常用实践运行 Elasticsearch 一类依赖 mmap 的组件时,其官方文档要求在宿主机上提高到 262144
核对方式查看进程的映射数量与上限的差距

典型使用场景

  • 部署搜索引擎:安装前按官方文档要求检查并提高宿主机上的该值
  • 应用报内存分配失败但系统内存充足:先排除映射数量触顶再查内存
  • 容器化部署:确认修改所在层级,容器内看到的限制可能与宿主不同
  • 容量评估:按索引分片数量估算单个进程可能需要的映射数
  • 故障复盘:把该值纳入交付检查项,避免同类问题在扩容后再次出现

查看与调整

查看与调整
sysctl vm.max_map_count                        # 读当前上限
wc -l /proc/$(pgrep -n java)/maps 2>/dev/null  # 用映射行数近似当前映射数量
grep -c . /proc/1/maps                         # 示例:统计某进程的映射条目数
sysctl -w vm.max_map_count=262144              # 临时调大
# 容器内修改可能被宿主或运行时限制,以在目标命名空间内的回读值为准

落盘与回读

落盘与回读
# /etc/sysctl.d/99-map-count.conf
vm.max_map_count = 262144    # 满足依赖 mmap 的组件对映射数量的要求
# 回读命令:sysctl vm.max_map_count

报错与方向对照

现象可能原因验证方式
Cannot allocate memory映射数量触顶查看进程 maps 行数是否接近上限
Cannot allocate memory物理内存与 swap 都不足查看 free、Committed_AS 与 OOM 日志
启动阶段即失败映射上限在初始化时已被用尽核对该值是否被镜像或运行时限制在较小值
只有部分实例失败单进程映射数量差异大对比各实例的映射数量与配置差异
虚拟内存映射数量与物理内存用量是两件事:一个进程可以有数十万映射而实际占用内存不大。因此这个值调高通常不会带来内存压力,但真正需要关注的是映射数量为何如此多,是否存在设计上的浪费。
容器场景要确认生效层级:宿主机修改后需要保证容器能读到新值,不同运行时与安全策略下的行为不一致。最可靠的做法是在容器内部用 sysctl 回读确认,而不是只核对宿主节点。

易错点

  • 把映射数量上限与内存容量混为一谈:调大上限不会导致内存不足,方向搞错会浪费排查时间
  • 只在宿主上调不核对容器内可见值:容器运行时可能屏蔽或重写该参数
  • 忽略交付检查项:扩容或重建节点后参数回到默认值,组件在启动时再次失败
  • 看到 Cannot allocate memory 就直接加内存:先确认是映射数量还是物理内存问题
  • 把上限调到极大来掩盖问题:映射数量异常增多往往说明程序存在文件打开或释放方面的缺陷

数据来源与参考

  • Linux 内核 Documentation/admin-guide/sysctl/vm.rst
  • Elasticsearch 官方文档(虚拟内存设置)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌