讲师中心 微信公众号
AI工具推荐 视频效率加速

Linux 内存泄漏排查方法总结

星辰君_9469

星辰君_9469

发布时间:2026-02-21 10:10:03

|

1036人浏览过

|

来源于php中文网

原创

判断内存泄漏需关注VmRSS持续上涨、free -h可用内存减少及swap启用,而非仅看top的%MEM;结合gdb堆分析、py-spy火焰图定位C层泄漏,并配置systemd内存限制与监控。

linux 内存泄漏排查方法总结

怎么看进程是不是在吃内存不放

直接看 /proc/[pid]/status 里的 VmRSS 和 VmSize,前者是实际物理内存占用,后者是虚拟地址空间大小。如果程序逻辑没变但 VmRSS 持续缓慢上涨,且 free -h 显示可用内存不断减少、swap 开始被用上,基本就是泄漏了。

别只盯 top 的 %MEM —— 它按比例算,小进程涨几百 KB 看不出;也别信 ps aux --sort=-rss 一眼扫完就下结论,得持续观察趋势。

  • 用 watch -n 1 'cat /proc/1234/status | grep -E "VmRSS|VmSize"' 替代肉眼刷新
  • 注意区分“缓存增长”和“泄漏”:Slab 或 PageCache 上涨可能是内核行为,查 /proc/meminfo 里 Slab、Cached 字段变化
  • 如果进程 fork 频繁(比如 CGI 模式),VmRSS 累加可能掩盖单次泄漏,优先抓子进程生命周期内的内存快照

gdb 调试运行中 C/C++ 进程的堆分配点

不是所有泄漏都能靠 valgrind 复现——生产环境不开调试符号、不能停服务、valgrind 本身慢 10 倍以上。这时候用 gdb 附加后查堆状态更实际。

前提是进程用了 glibc 默认 malloc,且没被 LD_PRELOAD 替换过分配器。先确认:cat /proc/[pid]/maps | grep libc.so 有输出,再进 gdb -p [pid]。

  • 执行 call malloc_stats() 打印当前堆统计(会输出到进程 stderr,确保它没被重定向丢弃)
  • 用 info proc mappings 找 heap 段地址,再 dump memory heap.bin [start] [end] 抓原始堆数据,后续用 strings heap.bin | grep -E "your_struct_name|malloc" 辅助定位
  • 容易漏:gdb 里 malloc 符号默认不加载,需先 set environment MALLOC_CHECK_=1 再 call malloc_stats(),否则可能返回空或报错 Cannot find bounds of current function

Python 进程 RSS 涨但 gc.get_objects() 数量不变怎么办

说明泄漏不在 Python 对象层,大概率在 C 扩展里(比如 numpy 数组没释放底层 buffer、ctypes 加载的 so 模块调用 malloc 后没 free、PIL 图片解码后内存没归还)。

Obsidian (Linux)
Obsidian (Linux)

操作 Obsidian 库(纯 Markdown 笔记),并通过 notesmd-cli 实现自动化。

下载

先排除常见陷阱:gc.disable() 没开、循环引用已清理、__del__ 没卡住对象——这些都检查完还涨,就得切到 C 层。

  • 用 py-spy record -p [pid] --duration 60 生成火焰图,重点看 libpython 外部的调用栈(比如 libjpeg.so、libz.so)
  • 检查是否用了 mmap:Python 的 mmap.mmap 不触发 GC,del 后仍占 VmRSS,必须显式调用 .close()
  • objgraph.show_growth() 只能看 Python 对象,对 numpy.ndarray 底层内存无效;要查它,得用 np.sum([arr.nbytes for arr in gc.get_objects() if isinstance(arr, np.ndarray)]) 算总字节数趋势

systemd 服务内存泄漏后自动重启的坑

加 Restart=on-failure 或 RestartSec=5 看似能兜底,但可能掩盖问题、放大影响:泄漏进程在重启前已把 OOM Killer 招来,顺手干掉其他重要服务;或者泄漏发生在初始化阶段,每次重启都重复加载大资源,加速系统崩溃。

更糟的是,systemd 默认不清除 cgroup 内存统计,MemoryCurrent 在重启后继续累加,导致 MemoryMax 限流失效。

  • 务必配 MemoryAccounting=true + MemoryMax=512M(按需调),并监控 systemctl show -p MemoryCurrent [service]
  • 重启前加钩子:ExecStopPre=/bin/sh -c 'echo $(date): RSS=$(cat /proc/$(cat /run/systemd/journal/stdout) | grep VmRSS | awk "{print \$2}")" >> /var/log/myapp-rss.log',留痕比猜有用
  • 不要依赖 OOMScoreAdjust=-1000 来保命——它只是降低被 kill 概率,不解决泄漏;真到了 OOM 阶段,kernel 日志里 Out of memory: Kill process 已经是最后一道防线了

内存泄漏最麻烦的不是找不到,是它常藏在你认为“不可能出问题”的路径里:一个日志模块的缓冲区没 flush、一次失败的 socket connect 留下的未 cleanup 的 SSL_CTX、甚至 strftime 在多线程下静态缓存导致的隐式增长。查的时候,少想“应该在哪”,多看“现在在哪”。

热门AI工具

更多
讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

3100

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

269

2026.02.03

sort排序函数用法
sort排序函数用法

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

1138

2023.09.04

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6247

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2628

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6247

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2628

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4438

2023.08.10

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

40

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn