opcache和jit是分层协作关系:opcache缓存字节码,jit在此基础上将热点字节码编译为机器码;jit必须依赖opcache.enable=1且opcache成功加载才能生效,否则opcache_get_status()['jit']为空或null。

OPcache 和 JIT 不是“二选一”的关系,而是分层协作:OPcache 缓存字节码(opcode),JIT 在此基础上对热点字节码进一步编译为机器码。没启用 OPcache,JIT 就没输入可处理——PHP 8 的 JIT 默认不生效,必须依赖 OPcache 启用后才激活。
opcache.enable=1 是 JIT 起效的硬性前提
PHP 8.0+ 中,opcache.jit 配置项(如 opcache.jit=1255)仅在 opcache.enable=1 且 OPcache 实际加载成功时才被读取。若只开 JIT 关 OPcache,或 OPcache 因配置错误未加载(比如 extension=opcache.so 被注释、路径错误、SELinux 拒绝 mmap),php -v 或 phpinfo() 中不会报错,但 opcache_get_status()['jit'] 始终为 null 或空数组。
- 检查是否真启用:
php -r "var_dump(opcache_get_status()['jit'] ?? 'not available');" - 确认共享内存就绪:
opcache_get_status()['memory_usage']['used_memory_human']应大于 0 - CLI 环境默认不启用 OPcache,需显式设
opcache.enable_cli=1才能让php -r测试反映真实行为
opcache.validate_timestamps=0 + 部署时 opcache_invalidate() 是生产环境安全组合
设 opcache.validate_timestamps=1(默认)会导致每次请求都对每个已缓存 PHP 文件调用 stat(),高并发下 I/O 和内核态切换飙升;但设为 0 后,文件更新不会自动生效——这正是生产环境需要主动管理缓存生命周期的原因。
- 不要用
opcache_reset()全局清空:它会清掉所有脚本(包括框架核心、Composer autoload),引发后续请求短暂性能抖动 - 推荐做法:部署脚本中遍历新版本中变更的
.php文件,逐个调用opcache_invalidate('/path/to/file.php', true)(第二个参数true强制重载) - 注意路径必须绝对且与运行时
require的路径一致,相对路径或符号链接可能导致失效失败
opcache.preload 预加载不是“多开一个开关”,而是一次性编译+内存驻留
预加载在 PHP-FPM master 进程启动时执行,把指定文件(及其递归 require 的文件)编译为字节码并锁进共享内存,Worker 进程 fork 后直接继承,不再解析、不占额外内存、不受 opcache.validate_timestamps 影响。
- 预加载文件里不能有运行时逻辑:
echo、file_get_contents(__FILE__)、date()等都会导致 preload 失败并中断整个进程启动 - 类名/函数名冲突会静默失败,建议在 preload 脚本末尾加
class_exists('App\Helper') || die('preload failed');做基础校验 -
opcache.preload_user必须设为 PHP-FPM worker 实际运行用户(如www-data),否则 preload 时因权限不足读不到文件,报Failed to open stream
opcache.optimization_level 控制的是字节码级优化,不是 JIT 开关
opcache.optimization_level 是位掩码,默认值 0x7FFFBFFF 已开启绝大多数静态优化(常量折叠、死代码消除、函数内联提示等)。它影响的是 OPcache 输出的字节码质量,进而决定 JIT 是否有足够“干净”的输入做进一步编译。
- 盲目调高(如设为
0xFFFFFFFF)可能引入兼容性问题,尤其在使用反射、动态方法调用(call_user_func)、eval 相关逻辑的项目中 - 调低(如
0x00000001)会禁用大部分优化,字节码更接近原始结构,JIT 可能反而更难识别热点模式 - 真正影响 JIT 行为的是
opcache.jit(触发策略)和opcache.jit_buffer_size(分配给 JIT 编译器的内存上限),二者缺一不可
最易被忽略的一点:OPcache 的共享内存段是否真正被所有 PHP 进程共享,取决于系统级配置(如 /proc/sys/kernel/shmmax)和 PHP 启动方式(FPM vs Apache mpm_event)。即使所有配置全对,若共享内存创建失败,OPcache 会静默退化为“只缓存不共享”,每个 worker 自己维护一份副本——此时内存占用翻倍、缓存命中率归零,而日志里几乎不报错。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











