0

0

Linux 内存分配与回收机制详解

舞夢輝影

舞夢輝影

发布时间:2026-01-29 19:13:03

|

131人浏览过

|

来源于php中文网

原创

从 Linux 5.13 开始,vmalloc() 默认尝试使用大页映射,但需满足空闲大页充足、地址对齐及分配大小足够(通常 ≥ 几十 KB)等条件;可通过启用 CONFIG_DEBUG_VM_VALLOC 查看 dmesg 日志或结合 /sys/kernel/debug/page_owner 分析页 order 确认,小内存系统慎用,启动参数 nohugevmalloc 可全局禁用。

linux 内存分配与回收机制详解

vmalloc() 用大页了吗?怎么确认?

从 Linux 5.13 开始,vmalloc() 默认尝试使用大页(huge pages)映射,但不是所有情况都生效——它依赖 zone 的空闲大页数量、对齐要求和分配大小。你不能靠 cat /proc/vmallocinfo 直接看出是否用了大页,因为该接口不暴露页粒度信息。

内核提供了 is_vm_area_hugepages(const void *addr) 这个内联函数来判断,但它依赖未导出的 find_vm_area(),所以**树外模块(比如你自己写的 ko)根本没法调用**。实际调试时,更可行的方式是:在内核配置中启用 CONFIG_DEBUG_VM_VALLOC,然后触发分配后检查 dmesg 是否出现 vmalloc(): using hugepage 类似日志;或者用 /sys/kernel/debug/page_owner 配合 addr 查看对应页的 order(order ≥ 2 通常意味着 4KB → 2MB 映射)。

  • 嵌入式小内存系统慎用:大页可能导致内部碎片,比如只申请 16KB 却占掉一个 2MB 大页
  • 启动时加 nohugevmalloc 参数可全局禁用,比运行时 patch 更可靠
  • 注意:即使启用了,vmalloc(4096) 也大概率还是用 4KB 页——大页只对 ≥ 几十 KB 的分配有收益

SLAB 回收为什么有时“卡住”不释放?

SLAB 分配器本身不主动回收 slab 缓存,而是等 kmem_cache_shrink() 被显式调用或由内存压力触发的 shrink_slab() 路径间接执行。常见现象是:你调了 kmem_cache_destroy(),但 /proc/slabinfo 里对应缓存项仍存在,甚至 slabinfo -a 显示 active_objs > 0。

原因通常是对象还在被引用:比如某个 struct 被放在链表里但没删干净,或被 RCU 持有未完成宽限期。SLAB 不会强制回收正在使用的对象,也不会等待 RCU 宽限期自动结束。

  • slabinfo -v cache_name 查看详细状态,重点关注 active_objsnum_objs 差值
  • RCU 场景下,必须确保所有 synchronize_rcu()call_rcu() 回调已执行完毕
  • 驱动模块卸载前,务必先清空所有对象引用,再调 kmem_cache_destroy(),否则可能 oops

OOM 前内存回收到底按什么顺序走?watermark 是怎么起作用的?

不是等 free 内存归零才回收,而是在空闲页低于 watermark[WMARK_LOW] 时就启动快速回收(kswapd),低于 watermark[WMARK_MIN] 则触发直接回收(alloc_pages() 中同步阻塞执行)。三个水位关系固定:min ,且 low = min + min/4,high = min + min/2。

PHP 网络编程技术与实例(曹衍龙)
PHP 网络编程技术与实例(曹衍龙)

PHP网络编程技术详解由浅入深,全面、系统地介绍了PHP开发技术,并提供了大量实例,供读者实战演练。另外,笔者专门为本书录制了相应的配套教学视频,以帮助读者更好地学习本书内容。这些视频和书中的实例源代码一起收录于配书光盘中。本书共分4篇。第1篇是PHP准备篇,介绍了PHP的优势、开发环境及安装;第2篇是PHP基础篇,介绍了PHP中的常量与变量、运算符与表达式、流程控制以及函数;第3篇是进阶篇,介绍

下载

关键点在于:kswapd 只负责把空闲页拉回 high 水位以上;一旦进程分配触发 direct reclaim,说明 low 都守不住了,此时回收路径会更激进(比如扫描更多 LRU 链表、尝试 swap、甚至考虑 OOM)。

  • 查看当前水位:grep -A10 "Node.*DMA\|Node.*Normal" /proc/zoneinfo
  • echo 1 > /proc/sys/vm/swappiness 并不能阻止 page cache 回收——只要 anon 和 file 页面都在 LRU 上,file 页面永远优先被回收
  • 频繁触发 direct reclaim?说明工作负载长期压着 low 水位跑,要么加内存,要么减少 mmap 大量文件或 tmpfs 使用

用户态看到的 “free 内存少”,真缺内存吗?

Linux 把大量空闲内存用于 page cache 和 slab,free 命令显示的 “available” 才是真正可立即分配的预估值(含可回收 cache)。很多运维第一反应是 kill 进程,但往往杀的是正在用 cache 加速 I/O 的进程,反而让磁盘变慢、延迟飙升。

真正要查的是:有没有进程在疯狂分配 anon 内存又不释放(如内存泄漏)、是否 swapin/si 持续升高(说明已在用 swap)、/proc/meminfoInactive(file) 是否远高于 Active(file)(cache 没被有效利用)。

  • 别信 top 里的 %MEM 排序结果——它算的是 RSS,包含共享库和 mmap 共享内存,不代表独占消耗
  • ps aux --sort=-vsz | head -10虚拟内存占用,再结合 pmap -x PID 看具体段分布
  • 如果 Available 还剩 1GB 以上,但系统卡顿,大概率是 I/O 或锁竞争问题,不是内存不足

水位计算是 per-zone 的,NUMA 系统里某 node 的 low 水位被击穿,可能只影响该 node 分配,不一定触发全局 OOM;而 slab 回收的时机藏在 shrink_slab() 的调用链深处,不深入到 mm/vmscan.c 很难看清它到底什么时候愿意放手。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

391

2023.09.04

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

531

2023.09.20

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

177

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

98

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1132

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

213

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1758

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

20

2026.01.19

clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

19

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8万人学习

Git 教程
Git 教程

共21课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号