0

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?

1 Answer 1

0

I could fix it by myself, sort of. It was a misconfiguration due to misunderstanding of the settings. As there are multiple PHP-FPM pools running, my understanding was that opcache.memory_consumption applies to each PHP-FPM pool, which is not the case. Thus, all PHP-FPM processes had 256 MiB available globally, and setting php_admin_value[opcache.memory_consumption] for a single master process does report 1 GiB as available, but since only 256 MiB of it is actually usable, the other 768 MiB are reported as used. And since the other pools fill the 256 MiB as well, there’s not much left and thus it’s always full.

I now changed the global configuration in php.ini to a larger value of 4 GiB and limit each pool to 256 MiB usable memory via php_admin_value[opcache.memory_consumption].

The only negative effect I could find is that opcache_get_status now returns a negative number for used memory.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.