宝塔任务管理器默认按CPU排序,而内存泄漏进程CPU低、RSS缓慢单向增长,需手动切内存列降序,过滤系统进程后重点查运行超30分钟、RSS超300MB且含php-cgi/node等关键词的驻留服务进程。

宝塔面板本身不提供内存泄漏的自动判定能力,所谓“隐藏泄漏”必须靠人工交叉比对进程 RSS 走势 + 启动时长 + 命令行特征来识别——不能只信首页数字,也不能只看任务管理器排序。
为什么宝塔任务管理器默认看不到泄漏线索
宝塔任务管理器默认按 CPU 使用率降序排列,而内存泄漏进程往往 CPU 很低(比如 php-cgi 空闲时只占 0.1%),但 RSS 持续缓慢爬升。你得手动点「内存」列标题切换为降序,再过滤掉 bash、sshd、systemd 这类系统进程,重点关注运行时间 >30 分钟、RSS >300MB 且名字含 php-cgi、node、gunicorn、python 的条目。
容易踩的坑:
- 把「已用内存高」直接当成泄漏——其实可能是
cached或buffers占用,真问题要看swap是否持续上涨、uss(独占物理内存)是否同步涨 - 忽略 CMD 字段:点进进程详情,如果
CMD显示的是/www/server/php/81/bin/php-cgi -b 127.0.0.1:9000这种长期监听模式,就不是一次请求生命周期,而是驻留服务,RSS 不回落才可疑
用 htop 实时验证 RSS 是否单向增长
htop 比 ps aux 更直观,能滚动查看历史 RSS 值变化趋势。先确保已安装:yum install -y htop(CentOS)或 apt install -y htop(Ubuntu)。启动后按 F6 → 选 PRESSURE_RSS 排序,再按 F5 展开树状视图,找到你的应用主进程(比如 node app.js 或 gunicorn master)。
关键操作:
- 盯住 RSS 列,观察 2–3 分钟:如果数值从 420MB → 428MB → 436MB 缓慢但稳定上升,且无明显回落,就是典型泄漏信号
- 按
F4输入php-cgi过滤,看所有 worker 的 RSS 是否普遍在 80–120MB 区间——若远高于此(比如 200MB+),说明某个 worker 已卡住并持续吃内存 - 对比
htop和宝塔任务管理器里同一进程的 RSS 值:若差值超过 50MB,大概率是宝塔刷新延迟或统计口径不同,以htop为准
结合日志确认泄漏是否由代码触发
光看 RSS 不够,得定位到具体哪段代码在漏。PHP 项目可在疑似入口函数前后加 memory_get_usage(true) 打点:
// 示例:在 Laravel 中间件或 ThinkPHP 控制器方法开头结尾 echo 'before: ' . memory_get_usage(true) . "\n"; // ... 业务逻辑 echo 'after: ' . memory_get_usage(true) . "\n";
注意:
- 用
memory_get_usage(true)(带true参数),返回的是实际分配的内存块大小,比默认值更准 - 别在循环里频繁打点——会干扰结果;只在请求入口和出口各打一次,连续发起 5–10 次相同请求,看「after」值是否逐次递增
- 如果
after值每次 +1MB,且不随请求结束释放,基本可断定该函数内有资源未释放(如 PDOStatement 未closeCursor()、GD 图像未imagedestroy())
Supervisor/PM2 进程反复重启其实是泄漏的间接证据
Supervisor 和 PM2 自身不报内存错误,但它们的日志里藏着泄漏线索:exited too quickly 或 start request failed: fork: Cannot allocate memory 都是系统 OOM Killer 干预后的结果。
查法:
- Supervisor:进宝塔「安全→系统工具→进程管理」,找到对应进程,点「日志」→ 查
.err.log,搜fork:或Cannot allocate memory - PM2:执行
pm2 show your-app-name,看restarts数值是否在 10 分钟内突增;再执行pm2 logs --lines 100,找FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - 别信「内存充足」——小内存 VPS(如 1GB)跑
pm2 start app.js默认用 1.7GB 内存上限,一旦泄漏超限就会被系统杀掉重拉,形成假性“稳定”
最易被忽略的一点:泄漏可能不在你写的业务代码里,而在某次 composer require 引入的第三方包中——比如一个用了全局静态数组缓存但没清理机制的 SDK。这时候得靠 valgrind --leak-check=full ./your-binary(C/C++)或 xdebug 内存分析(PHP)进一步下钻,不能只盯着宝塔界面看。


















