While checking my server I noticed that PHP’s OPcache is completely full, despite having enough scripts stored to fill the space.
opcache_get_status returns this:
array(8) { ["opcache_enabled"]=> bool(true) ["cache_full"]=> bool(true) ["restart_pending"]=> bool(false) ["restart_in_progress"]=> bool(false) ["memory_usage"]=> array(4) { ["used_memory"]=> int(1073664976) ["free_memory"]=> int(4056) ["wasted_memory"]=> int(72792) ["current_wasted_percentage"]=> float(0.006779283285140991) } ["interned_strings_usage"]=> array(4) { ["buffer_size"]=> int(25165824) ["used_memory"]=> int(17389344) ["free_memory"]=> int(7776480) ["number_of_strings"]=> int(187268) } ["opcache_statistics"]=> array(13) { ["num_cached_scripts"]=> int(4244) ["num_cached_keys"]=> int(4996) ["max_cached_keys"]=> int(16229) ["hits"]=> int(854552) ["start_time"]=> int(1748005092) ["last_restart_time"]=> int(0) ["oom_restarts"]=> int(0) ["hash_restarts"]=> int(0) ["manual_restarts"]=> int(0) ["misses"]=> int(236764) ["blacklist_misses"]=> int(0) ["blacklist_miss_ratio"]=> float(0) ["opcache_hit_rate"]=> float(78.30472567065819) } ["jit"]=> array(7) { ["enabled"]=> bool(false) ["on"]=> bool(false) ["kind"]=> int(5) ["opt_level"]=> int(4) ["opt_flags"]=> int(6) ["buffer_size"]=> int(0) ["buffer_free"]=> int(0) } } However, the actual size of all scripts cached in OPcache is only 96.95 MiB. Also, the space is already immediately used after restarting the PHP process (via FPM). While I would be okay if memory consumption is roughly twice the size of the scripts, more than 10 times doesn’t sound okay.
PHP configuration:
opcache.enable True opcache.enable_cli False opcache.use_cwd True opcache.validate_timestamps True opcache.validate_permission False opcache.validate_root False opcache.dups_fix False opcache.revalidate_path False opcache.log_verbosity_level 1 opcache.memory_consumption 1.00 G opcache.interned_strings_buffer 24.00 M opcache.max_accelerated_files 10,000 opcache.max_wasted_percentage 5.0% opcache.consistency_checks 0 opcache.force_restart_timeout 180 seconds opcache.revalidate_freq 5 seconds opcache.preferred_memory_model "" opcache.blacklist_filename "" opcache.max_file_size 0.00 B opcache.error_log "" opcache.protect_memory False opcache.save_comments False opcache.record_warnings False opcache.enable_file_override False opcache.optimization_level 1111111111111101011111111111111 opcache.lockfile_path "/tmp" opcache.file_cache "" opcache.file_cache_only False opcache.file_cache_consistency_checks True opcache.file_update_protection 2 opcache.opt_debug_level 0 opcache.restrict_api "" opcache.huge_code_pages False opcache.preload "" opcache.preload_user "" opcache.jit "tracing" opcache.jit_buffer_size 0 opcache.jit_debug 0 opcache.jit_bisect_limit 0 opcache.jit_blacklist_root_trace 16 opcache.jit_blacklist_side_trace 8 opcache.jit_hot_func 127 opcache.jit_hot_loop 64 opcache.jit_hot_return 8 opcache.jit_hot_side_exit 8 opcache.jit_max_exit_counters 8,192 opcache.jit_max_loop_unrolls 8 opcache.jit_max_polymorphic_calls 2 opcache.jit_max_recursive_calls 2 opcache.jit_max_recursive_returns 2 opcache.jit_max_root_traces 1,024 opcache.jit_max_side_traces 128 opcache.jit_prof_threshold 0 I also already tried allowing using more memory for OPcache (up to 4 GiB), but also this got consumed immediately. I also couldn’t find a difference between PHP 8.3 and PHP 8.1.
I already tried disabling opcache.jit entirely (via opcache.jit=disable), which didn’t make any difference.
Any clue, why this happens?