一、为什么要重视内存
Linux 应用运行时间越长,内存问题越容易暴露。短时间测试正常,不代表长期运行稳定。内存泄漏、越界访问、重复释放、use-after-free 都可能导致崩溃、性能下降或系统被 OOM killer 杀死。
常见内存问题:
- 内存泄漏。
- 空指针访问。
- 数组越界。
- 重复释放。
- 释放后继续使用。
- 栈空间不足。
- 内存碎片。
二、进程内存布局
一个 Linux 进程大致包含:
1 | text 代码段 |
查看进程内存映射:
1 | cat /proc/<pid>/maps |
查看内存统计:
1 | cat /proc/<pid>/status |
重点字段:
VmSize:虚拟内存大小。VmRSS:实际驻留物理内存。VmData:数据段和堆。VmStk:栈。
三、malloc 和 free
示例:
1 |
|
建议:
malloc后检查返回值。- 谁申请,谁释放,规则要清楚。
free后把指针置空。- 不要返回局部变量地址。
- 不要越界写入。
四、典型错误
4.1 内存泄漏
1 | void leak(void) { |
函数结束后 buf 丢失,内存无法释放。
4.2 use-after-free
1 | char *buf = malloc(128); |
释放后继续使用,行为未定义。
4.3 越界写
1 | char buf[8]; |
会破坏栈上其它数据,严重时直接崩溃。
五、AddressSanitizer
编译:
1 | gcc main.c -o app -g -fsanitize=address -fno-omit-frame-pointer |
运行:
1 | ./app |
AddressSanitizer 可以发现:
- 越界访问。
- use-after-free。
- double free。
- 部分内存泄漏。
开发阶段建议经常用它跑测试。
六、Valgrind
安装:
1 | sudo apt install -y valgrind |
检查泄漏:
1 | valgrind --leak-check=full ./app |
特点:
- 不需要重新编译。
- 能输出详细泄漏位置。
- 运行速度慢。
七、线上内存排查
查看进程内存:
1 | ps aux --sort=-%mem | head |
查看单进程:
1 | cat /proc/<pid>/status |
持续观察:
1 | watch -n 1 'cat /proc/<pid>/status | grep VmRSS' |
如果 VmRSS 持续增长且没有回落,可能存在泄漏。
八、OOM killer
系统内存不足时,内核可能杀死进程。
查看日志:
1 | dmesg | grep -i "killed process" |
或:
1 | journalctl -k | grep -i oom |
嵌入式设备内存更小,更容易遇到 OOM。
九、工程建议
- 明确对象生命周期。
- 封装申请和释放。
- 错误分支也要释放资源。
- 大块内存复用,避免频繁申请释放。
- 长期运行服务要做压力测试。
- CI 中加入 AddressSanitizer 测试。
十、总结
内存问题的特点是隐蔽、偶发、破坏性强。开发阶段用 AddressSanitizer,专项排查用 Valgrind,线上观察 /proc、日志和 OOM 记录。
稳定的 Linux 程序,一定要把内存生命周期设计清楚。
- 本文链接: https://blog.hansong.icu/2026/06/21/Linux_Dev_Memory_Management/
- 版权声明: 本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。