唯一稳定路径是用Xdebug生成cachegrind.out文件后由QCacheGrind打开;需设xdebug.mode=profile、output_dir并重启服务,注意权限、文件名匹配及JIT冲突;分析时重点关注Incl./Self Wall Time两列,I/O热点可搜索定位,但profile不反映OPcache状态与FPM冷热差异。

直接用 Xdebug 生成 cachegrind.out 文件,再丢给 QCacheGrind(不是 KCacheGrind)打开——这是唯一稳定、可复现的路径。所谓“KCacheGrind”是 KDE 环境下的旧版 GUI,现在主流用的是跨平台的 QCacheGrind,名字常被误传,但工具链没变。
怎么让 PHP 输出 cachegrind.out 文件
必须用 Xdebug,并且只在开发环境开。生产环境禁用——它会让请求慢 5–10 倍。
- 确认
xdebug.mode包含profile:在php.ini里设xdebug.mode = profile - 指定输出目录:
xdebug.output_dir = /tmp/xdebug(确保该目录存在且 PHP 进程有写权限) - 重启 PHP-FPM 或 Apache:比如
systemctl restart php-fpm-81 - 触发一次请求(如访问某个接口),就会在
/tmp/xdebug/下生成类似cachegrind.out.12345的文件
QCacheGrind 打不开?检查这三点
常见打不开或空白,基本卡在这几个地方:
- 文件权限不对:
chown www-data:www-data /tmp/xdebug/cachegrind.out.*(根据你 PHP 运行用户调整) - 文件名带 PID 但没匹配上:QCacheGrind 默认只读
cachegrind.out.*,不认callgrind.out.*,别手动改名 - PHP 版本 ≥ 8.0 且用了 JIT:Xdebug 与 JIT 共存时可能生成损坏的 profile 文件;临时关 JIT 测试:
ini_set('opcache.jit', '0');
调用图里怎么看性能热点
打开后别急着看火焰图——先盯住两个核心列:
立即学习“PHP免费学习笔记(深入)”;
-
Incl. Wall Time:函数自身 + 所有子调用总耗时 → 找「整条链最重的入口」 -
Self Wall Time:函数自己干的活耗时 → 找「真正该优化的函数体」 - 右键某函数 → “Jump to caller/callee” 快速跳转调用上下文
- 顶部搜索框输
mysqli_query或file_get_contents,能立刻定位 I/O 热点
真正容易被忽略的是:Xdebug profile 不记录 OPcache 命中/未命中细节,也不体现 FPM worker 复用带来的冷热差异。如果看到某函数耗时波动极大,先确认是不是第一次请求(OPcache 编译期)和后续请求混在一起分析了——建议用 perf_add_marker() 手动打点切分关键段,比依赖全量 profile 更准。



















