memory_get_peak_usage()返回字节数,$real_usage=false时统计PHP管理器分配量,true时统计系统级真实分配量,单位均为字节。

memory_get_peak_usage 返回的到底是啥单位
memory_get_peak_usage() 返回的是字节数,不是 KB 或 MB。直接 echo 会看到一串大数字,比如 2097152,其实是 2MB。别急着除以 1024 再除一次——先确认是否需要格式化输出,否则后续做阈值判断时用错单位会导致逻辑错误。
常见误用:
- 把返回值当成 KB 比较(比如写 if (memory_get_peak_usage() > 10) { ... },实际是 10 字节,永远不触发)
- 格式化时混淆二进制/十进制换算(1MB = 1024×1024 字节,不是 1000×1000)
实操建议:
- 判断内存超限:统一用字节比较,例如限制 16MB → memory_get_peak_usage() > 16 * 1024 * 1024
- 日志或调试输出时再转为易读格式,例如:sprintf('%.2f MB', memory_get_peak_usage() / 1024 / 1024)
为什么脚本结束前调用 memory_get_peak_usage 总是不准
PHP 的内存峰值统计依赖于 Zend 引擎的内存管理器,而某些操作(如 GC 回收、扩展释放资源、OPcache 清理)可能在脚本“逻辑结束”后才真正发生。如果你在 register_shutdown_function() 里调用 memory_get_peak_usage(),结果往往比真实峰值低。
更可靠的做法:
- 在关键路径末尾、所有业务逻辑完成但尚未进入清理阶段时主动记录,例如函数返回前、循环结束后
- 避免依赖 __destruct 或 shutdown 函数——它们执行时内存状态已不可控
- 如果必须在退出时捕获,加一句 gc_collect_cycles() 强制触发一次回收,再调用 memory_get_peak_usage(),能减少误差
real_usage 参数为 true 和 false 的区别很关键
memory_get_peak_usage() 第一个参数是 $real_usage,默认为 false。这个开关直接影响统计口径:
当 $real_usage = false(默认):
- 统计 PHP 内存管理器“认为”已分配的内存(含内部碎片、预留池等)
- 数值偏小,但反映的是脚本实际申请行为,适合做性能对比
当 $real_usage = true:
- 调用底层 malloc 实际向系统申请的内存块大小
- 数值更大,包含对齐填充、分配器开销,更接近系统级观测值(如 ps 看到的 RSS)
- 在排查 OOM 或容器内存限制问题时更有参考价值
实操建议:
- 开发调试阶段用 false(默认),关注代码自身行为
- 生产环境监控或对接 cgroup 限额时,显式传 true,例如:memory_get_peak_usage(true)
CLI 和 Web SAPI 下的峰值差异容易被忽略
同一个脚本,在 CLI 模式下跑出来的 memory_get_peak_usage() 值,通常比 Apache/FPM 下低 1–3MB。这不是 bug,而是 SAPI 层初始化带来的固定开销:Web SAPI 预加载了更多扩展、路由上下文、请求缓冲区等。
立即学习“PHP免费学习笔记(深入)”;
这意味着:
- 不要在 CLI 测试时按 Web 环境的内存阈值设限,否则上线后频繁触发 Fatal error: Allowed memory size exhausted
- 自动化压测时,务必在目标 SAPI 环境中采集基线值
- 查看真实 Web 请求峰值,可在响应头注入:header('X-Memory-Peak: ' . memory_get_peak_usage(true));,配合日志分析
复杂点在于:FPM worker 进程复用、OPcache 预热状态、甚至 FastCGI 缓冲策略都会让每次请求的峰值浮动。单次调用 memory_get_peak_usage() 只能反映当前请求,不能代表长期趋势。



















