frankenphp启用worker模式后,rss应快速爬升后持平;若10分钟内持续上升(每分钟涨超2–3mb)、memory_get_peak_usage(true)单调递增、opcache oom_count非零或minfl持续超2000,则存在内存泄漏或配置失衡。

看 worker 进程 RSS 是否不再阶梯式上涨
FrankenPHP 启用 worker 模式后,内存不该随请求数线性增长——稳定状态下,RSS(物理内存)应快速爬升后持平。若连续观察 10 分钟仍持续上升,大概率存在泄漏或缓存未复用。
执行以下命令实时盯住主 worker 进程(假设只有一个):
watch -n 1 'ps -o pid,rss,comm -p $(pgrep -f "frankenphp-worker")'
重点关注 rss 列:单位是 KB,若每分钟上涨超 2–3MB 且无回落,就不是“预热”,而是泄漏信号。注意别误把 OPcache 内存(在进程内部管理,不体现在 RSS)当成本体增长。
- 首次启动后 RSS 上升是正常的(加载框架、OPcache 编译等),但 2–3 分钟内应收敛
- 如果
rss在某值附近小幅波动(±5MB),属于健康状态 - 若出现单次请求后 RSS 突增 20MB+ 且不释放,立刻检查该请求路径是否加载了大文件、未关闭资源句柄或调用了
unserialize()不可信数据
查 memory_get_peak_usage(true) 日志是否周期性归零
worker 进程常驻,但 PHP 的内存分配器不会无限扩张;每次请求结束时会释放大部分内存,memory_get_peak_usage(true) 能反映单次请求真实峰值。若它持续走高不回落,说明有全局变量、静态属性或闭包引用意外持有了资源。
在控制器关键入口加一行打点:
error_log(sprintf('PID:%d req:%d mem_peak:%d', getmypid(), $_SERVER['REQUEST_TIME_FLOAT'], memory_get_peak_usage(true)));
用 wrk -t2 -c10 -d60s 发 60 秒请求,再 grep 日志:
grep 'mem_peak' storage/logs/laravel.log | tail -50 | awk '{print $NF}' | sort -n
- 输出数值应在一个区间内抖动(如 8.2M–9.7M),而非单调递增(如 8.2M → 9.1M → 10.3M → 11.6M)
- 若发现某次请求峰值突然跳到 50M+,结合日志时间戳定位对应 URL 和参数,大概率是那个接口触发了异常加载
- 别只看
memory_get_usage(),它不含未用内存块,容易掩盖碎片问题
对比 opcache_get_status() 中 oom_count 和 memory_usage.used_memory
OPcache 占用的是独立内存池,但它一旦爆满,会触发 PHP 层级的 GC 压力,间接拖慢 worker。必须确认 OPcache 自身没成为内存黑洞。
访问 /frankenphp/status 或在脚本中调用:
<?php $s = opcache_get_status(); echo $s['opcache_statistics']['oom_count'] . "\n"; echo $s['memory_usage']['used_memory'] . "\n"; ?>
-
oom_count必须为0;非零说明 OPcache 内存池已耗尽,新脚本无法编译,降级回解释执行,CPU 不高但延迟飙升 -
used_memory应稳定在opcache.memory_consumption * 0.7以内;长期 > 90% 表示缓存项太多或max_accelerated_files设得太小,引发频繁淘汰 - 若
opcache_get_status()['scripts']数量远超项目实际 PHP 文件数(比如 1200 个脚本但只有 300 个源码),说明有动态生成代码(如 Twig 编译缓存)未被正确清理
用 pidstat -r -p $(pgrep frankenphp) 看 page-fault 频率
RSS 稳定 ≠ 内存访问高效。大量 minor page fault(次要缺页)说明进程在反复申请/释放小块内存,虽不触发 OOM,但会显著拖慢响应——尤其在高并发下,内核处理缺页的开销会集中爆发。
运行:
pidstat -r -p $(pgrep frankenphp) 2
观察 MINFL(minor fault)列:
- 稳定 worker 下,每秒
MINFL应 ≤ 500;若持续 > 2000,说明内存分配模式有问题(比如高频 new 对象 + unset,或字符串拼接未用str_replace替代正则) - 注意区分
MAJFL(major fault):> 0 就危险,表示在从磁盘换入页面,基本等于性能已崩 - 这个指标比 RSS 更早暴露问题——RSS 还没涨,
MINFL可能已经翻倍
真正的稳定不是数字不动,而是 RSS、peak_usage、OPcache 使用率、page fault 四者同步进入低抖动区间。任何一项持续偏离,都意味着某个环节的约束没对齐——比如 memory_limit 设得比容器 mem_limit 还高,或者 OPcache 缓存了不该缓存的调试类。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











