zend_extension
more precisely, which is shipped into the PHP source code, starting from PHP 5.5.0 (Pecl for others), and that must be activated through the normal php.ini process of activating an extension. For distros, please refer to your distribution manual to know how PHP and OPcache have been bundled.INI
setting opcache.preferred_memory_model
allows you to explicitly select the memory model you want.
If you leave the parameter to a null value, OPcache will select the first model which works for your platform, iterating through its table:mmap
should be used. It's a nice memory model, mature and robust. However, it is less informative to the sysadmin that System-V SHM model is, and its ipcs
and ipcrm
commands.opcache.memory_consumption
INI setting (Megabytes). Size it big, don't hesitate to give space. Never ever run out of shared memory space, if you do, you will lock your processes, we'll get back to that later.persistent_script
structure, instead of it filling directly the Zend Engine tables and internal structures.persistent_script
structure:persistent_script
ones, simple function pointers switch:persistent_script
structures. Then OPcache will have to browse those structures, and replace request allocated pointers to shm ones. OPcache is interested in:ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION
and ZEND_COMPILE_DELAYED_BINDING
. That would add more work to OPcache. Remember that OPcache hooks into the Zend Engine, it is not a source code patch.persitent_script
structure, we must cache its information. Remember that the PHP Compiler has filled-in our structures, but it allocated the memory behind this using the Zend Memory Manager; this memory will be freed at the end of the current request. We then need to browse this memory and copy all of it into the shared memory segment, so that the information we just gathered will now persist through several requests and won't need to be recomputed every time.ZCG(mem)
represents the fixed-size shared memory segment and is filled-in as elements are added. It then has already been allocated, there is no need to allocate memory on each copy (which would have been less performant), but simply fill-in the memory, and move forward the pointer address border.persistent_script
back from shared memory and browse each of its dynamic structures to duplicate every shared pointer to a request-bound allocated pointer.opcache.interned_strings_buffer
INI setting. Monitor OPcache and once more; make sure you have enough memory.opcache.interned_strings_buffer
setting is too low), OPcache will not trigger a restart, because it still has some shm available, only interned strings buffer is full, which is not blocking to continue processing request, you'll simply end up having some strings interned and shared, and some other that use PHP worker's memory. I don't recommend that for performance.opcache.blacklist-filename
INI setting (which accepts glob patterns).fcntl()
call.opcache.revalidate_freq
INI setting), and will have a hint of whether the file is fresh or stale.stat()
ed the file; OPcache just reuses this information and does not issue a costly stat()
call to the filesystem again for its own use.opcache.validate_timestamps
and opcache.revalidate_freq
, and your file has effectively changed, then OPcache will simply invalidate it, and flag all of its shm data as invalid.opcache.max_wasted_percentage
INI setting value, OPcache will trigger a full restart, which is something you must absolutely prevent from happening No other scenario.opcache_reset()
) or directly shut down FPM (better, we'll detail in few minutes).lsof
and kill
in case some hard requests don't seem to finish. Bring your Unix knowledge ;-).opcache_get_status()
function:opcache.revalidate_path
to 1 and empty your realpath cache (which may be hard to do as it is bound to the PHP worker process handling the current request).opcache.revalidate_path
INI setting turned to 1. If not, OPcache will also use the unresolved path as a cache key, and that will lead to problems if you were using symlinks, because if you then change the symlink target, OPcache will not notice it, as it will still use the unresolved path as key to find the old targetted script (this is to save a symlink resolution call).opcache.use_cwd
to 1, you tell OPcache to prepend the cwd
to every key, in case you use relative paths to include your files, like require_once "./foo.php";
. I suggest, if you use relative paths and host several applications on the same PHP instance (which you shouldn't do), to always put opcache.use_cwd
to 1. Also, if you happen to play with symlinks, turn opcache.revalidate_path to 1. But even with those settings on, you will suffer from PHP's realpath cache, and you may change the www symlink to another target, it won't be noticed by OPcache, even if you empty the cache by using opcache_reset()
.opcache_get_status()
, a function the different GUIs rely on. The num_cached_keys
dimension returned by this function gives the info. You should preconfigure the number of keys, as a hint, using opcache.max_accelerated_files
INI setting.require_once
statements, it makes OPcache generate more keys. Using an autoloader is recommended, as this one, if well configured, will always issue include_once
calls with full paths, and not relative ones.num_cached_scripts
a dimension which is different from the num_cached_keys
dimension, from OPcache status report. Only the num_cached_keys
info is relevant if it reaches max_cached_keys,
you'll be in trouble with a restart pending.opcache.log_verbosity_level
INI). It tells you if it runs out of memory, and which kind of OOM (OutOfMemory) error it generated; if it is related to the shm being full, or if it is the keys Hashtable which is full.opcache.memory_consumption
Megabytes of shared memory (shm) from the OS.opcache.interned_strings_buffer
). After that, it preallocates the HashTable for future persistent scripts and their keys to be stored. The space used depends on the opcache.max_accelerated_files
.opcache.validate_timestamps
to 0).opcache.memory_consumption
, the most important.opcache.interned_strings_buffer
, monitor your usage, and size accordingly, take care if you tell OPcache to save comments, which you will likely do if you use PHP "annotations" .(opcache.save_comments
= 1), those are strings, big strings, that will eat your interned strings bufferopcache.max_accelerated_files
, numbers of keys to preallocate, once more: monitor and size accordingly.opcache.opcache.revalidate_path
and opcache.use_cwd
. That will save some keyspace.opcache.enable_file_override
, this will accelerate the autoloader.opcache.blacklist_filename
list with the script names you are likely to generate during runtime; shouldn't be too many of them anyway.opcache.consistency_checks
, this basically checks a control sum on your scripts, that eats perf.opcache.max_wasted_percentage
is not very useful in this case.