如何统计通过Symfony Process组件运行的脚本的实际内存占用量
你的判断完全正确
Symfony Stopwatch组件的getMemory()方法统计的是当前执行的PHP主进程的内存占用,和你通过Process组件启动的Python子进程完全无关,拿到的数值自然不是Python脚本的内存消耗。
统计Python脚本内存占用的方案
- 方案1:通过GNU time命令注入统计(无侵入,无需修改Python代码)
直接在你要执行的Python命令前拼接GNU time指令,指定输出最大常驻内存的格式,执行后解析Process的输出即可拿到Python进程的峰值内存:
注意需要使用GNU time(而非shell内置的time命令),多数Linux发行版默认已安装,路径一般为
/usr/bin/time
// 拼接time命令,%M会输出进程峰值常驻内存,单位为KB $wrappedCmd = ['/usr/bin/time', '-f', '%M', ...$somePythonCmd]; $process = new Process($wrappedCmd, null, ['PYENV_VERSION' => 'unicornenv']); $process->start(); $process->wait(); // 解析输出,time的统计结果会输出到stderr,注意如果你的Python脚本本身有stderr输出需要做区分 $output = $process->getErrorOutput(); preg_match('/(\d+)$/', trim($output), $matches); $pythonPeakMemoryKb = $matches[1] ?? 0;
- 方案2:通过子进程PID轮询统计(支持实时获取内存峰值)
Symfony Process启动后可以直接拿到子进程的PID,你可以替换原来的wait()为轮询逻辑,过程中定期查询PID对应的内存消耗,记录峰值:
$process = new Process($somePythonCmd, null, ['PYENV_VERSION' => 'unicornenv']); $process->start(); $pid = $process->getPid(); $peakMemoryKb = 0; while ($process->isRunning()) { // 执行ps命令查询当前PID的常驻内存 $memResult = shell_exec("ps -o rss= $pid"); $currentMemKb = (int)trim($memResult); if ($currentMemKb > $peakMemoryKb) { $peakMemoryKb = $currentMemKb; } // 控制轮询频率,避免占用过多资源 usleep(100000); // 100ms轮询一次 }
- 方案3:Python脚本自行统计(最精准,适合可修改Python代码的场景)
在Python脚本中引入psutil库,自行统计内存占用,执行结束后将内存结果输出到stdout/stderr,PHP侧直接解析即可:
import psutil import os # 你的业务逻辑... # 结束时输出峰值内存 process = psutil.Process(os.getpid()) peak_memory = process.memory_info().rss / 1024 # 单位转换为KB print(f'PYTHON_MEM_STAT:{peak_memory}', flush=True)
PHP侧拿到输出后匹配对应前缀的行解析即可。
内容的提问来源于stack exchange,提问作者gherkins
相关产品推荐
相关产品推荐

