⭐ 推荐:社区规则条款 V1.0

PHP OPcache 调优指南:jit、内存与命中率的参数怎么配

最长的电影
最长的电影 正式会员正式会员
发布于 2026-08-03 22:16 ·87 浏览 ·0 回复
内容摘要

OPcache 调优需将内存、字符串池和缓存文件数三个参数一起按站点规模配足,生产环境关闭 validate_timestamps 以把命中率从90%多提升到99%以上,代价是改代码后须重启 PHP-FPM 或执行 opcache_reset;JIT 仅适用于 PHP 8.0+,可从 jit_buffer_size=64M、jit=1255 起步,但收益通常小于基础参数配好。

OPcache 调优其实就三件事:内存给够、文件数算准、生产环境把 validate_timestamps 关掉;JIT 是 PHP 8.0 以后才有的加分项,Web 场景从 opcache.jit_buffer_size=64M + opcache.jit=1255 起步即可,收益远小于前三个参数没配对带来的损失。

先把三个基础参数按比例配好

结论:opcache.memory_consumption、opcache.interned_strings_buffer、opcache.max_accelerated_files 必须一起调,只调其中一个基本等于没调。

  • opcache.memory_consumption:缓存编译后字节码的内存。小型站点 128M 够用,中型社区 192M–256M。给太小会触发缓存淘汰,表现为命中率上不去、CPU 反而升高。
  • opcache.interned_strings_buffer:驻留字符串池,默认 8M。PHP 8 时代各类框架/插件字符串多,建议 16M–32M,这个值偏小是「内存明明够却频繁重启缓存」的常见原因。
  • opcache.max_accelerated_files:能缓存的脚本文件数上限。它会被系统向上取到质数集合里最接近的值,所以填 10000 实际生效的可能是 10691,不用纠结精确数字。经验算法:项目 PHP 文件数 × 2 起步。Clara BBS 这类插件化系统,插件目录 content/plugins 会随安装数量增长,建议直接给 20000。

三者的关系是:文件数不够 → 旧脚本被挤掉;字符串池不够 → 共享内存快速耗尽;内存不够 → 两者一起崩。所以要么全给足,要么别开。

validate_timestamps 决定你的命中率上限

结论:生产环境设 opcache.validate_timestamps=0,这是命中率从 90% 出头拉到 99%+ 的关键一步。

默认 validate_timestamps=1,OPcache 每隔 opcache.revalidate_freq 秒(默认 2 秒)去 stat() 每个脚本文件,看时间戳有没有变。文件一多,这堆 stat 系统调用本身就吃掉不少 IO。关掉之后 OPcache 完全信任内存里的字节码,不再回查磁盘。

代价是:改了 PHP 文件不会自动生效,必须重启 PHP-FPM 或调用 opcache_reset()。所以开发机、以及还在频繁改代码/装插件的站点,保持 validate_timestamps=1、revalidate_freq=60 更省心;正式上线且代码冻结了再关。

这里有个容易混淆的点:Clara BBS 的模板和插件是运行时钩子加载、保存即生效、不写编译缓存的,后台「系统工具→缓存清理」清掉的是站内应用缓存(Cache::remember 那一层),跟 PHP 的 OPcache 不是一回事。所以别指望点一下「缓存清理」去刷新 OPcache——关了 validate_timestamps 之后,正确做法是重启 PHP-FPM。

JIT 怎么配:版本、模式和容量

结论:JIT 只在 PHP 8.0+ 存在,PHP 7.4 没有这个选项,写进 php.ini 会被忽略;开启的最小配置是 opcache.jit_buffer_size=64M + opcache.jit=1255。

注意 jit_buffer_size 默认是 0,也就是说 PHP 8 装好了 JIT 默认也是关的,必须显式给值。

opcache.jit 是个四位数字,Web 应用常见的两档:

  • opcache.jit=1205:函数级 JIT,编译开销小,适合请求短、代码路径分散的场景。
  • opcache.jit=1255:tracing 模式,热点循环优化更彻底,适合计算密集代码。多数跑 PHP 8.2/8.3 的社区站可以直接用 1255。

JIT 对纯数据库+模板渲染的 Web 请求收益通常只有个位数百分比,别期待翻倍;真正吃到红利的是图像处理、加解密、复杂循环这类 CPU 密集逻辑。另外 JIT 缓冲区是从共享内存里另算的,开了 128M 的 JIT 就意味着 PHP 进程组多占 128M,小内存机器别贪大。

两个验证动作:看命中率、看缓存是否被打满

结论:调完不看 opcache_get_status() 就是盲调,命中率和 wasted_memory 是两个必看指标。

在站点根目录临时放一个脚本,打印 opcache_get_status(false),重点看三项:

  1. opcache_hit_rate:稳定运行几天后应高于 99%;
  2. memory_usage.free_memory:长期接近 0 说明内存给小了;
  3. memory_usage.wasted_memory 与 current_wasted_percentage:持续增长说明不断有脚本被淘汰,通常是 max_accelerated_files 或字符串池不够。

顺手再确认 opcache.enable=1、opcache.enable_cli=0(除非你跑常驻 CLI 队列,Web 场景开 CLI 版纯属浪费内存)。云面板用户改完记得重启 PHP 服务,改 php.ini 不重启是不生效的。

收束

顺序别搞反:先按文件数×2 给 max_accelerated_files,再给 128M–256M 的 memory_consumption 和 16M 起步的字符串池,生产环境关掉 validate_timestamps,最后才考虑 PHP 8+ 的 JIT(jit_buffer_size=64M、jit=1255)。上线后用 opcache_get_status() 复核命中率与碎片,按数据再微调,比抄一份别人的 php.ini 靠谱得多。

本文转载自 Clara轻量论坛系统,原文地址:https://www.leleweb.cn/thread-387.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 0

还没有回复,来抢沙发~