A PHP worker has two lifecycles, one inside the other. At process start, module startup (MINIT) reads php.ini, loads extensions and attaches to OPcache's shared memory. Then, for every request, request startup (RINIT) fills $_GET, $_SERVER and the other superglobals; the script is compiled to opcodes, or taken ready-made from OPcache, and executed; and request shutdown (RSHUTDOWN) runs destructors, flushes output and frees every variable the request created.

The next listing makes both lifecycles visible:
<?php
static $hits = 0;
$hits++;
$ms = (microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000;
$op = opcache_get_status(false);
printf("pid %d hits %d opcache hits %d %.2f ms\n",
getmypid(), $hits, $op['opcache_statistics']['hits'] ?? 0, $ms);Requested five times through Apache 129 with mod_php, it prints:
pid 27533 hits 1 opcache hits 0 0.92 ms pid 27534 hits 1 opcache hits 1 0.63 ms pid 27530 hits 1 opcache hits 2 0.22 ms pid 27531 hits 1 opcache hits 3 0.19 ms pid 27532 hits 1 opcache hits 4 0.18 ms
$hits is 1 every time because RSHUTDOWN destroyed it; under PHP-FPM, one worker answered two of five requests and printed 1 both times. The OPcache counter climbs because compiled scripts live in shared memory: the first request paid for compilation, later ones ran in about 0.2 ms. A file modified in the last two seconds is not cached yet (opcache.file_update_protection). Performance and OPcache tunes OPcache.