Skip to content

OPCache wasted memory increases on each request #9917

@icedevelopment

Description

@icedevelopment

Bug Report

Q A
BC Break no
Version 2.12.3

Summary

The OPCache wasted memory increases on each request if a paginator is used.

Current behavior

Whenever you make a request on a controller with a Doctrine\ORM\Query that uses Doctrine\ORM\Tools\Pagination\Paginator#getIterator(), the DQL to SQL parser cache is redone each time.
Seems that this is bad a side effect introduced in commit 023e946 which was merged in 2.6.5 so every version between this and 2.12.3 should be impacted.

How to reproduce

  1. Install a Symfony app with Doctrine with the following standard cache configuration:
# config/packages/prod/doctrine.yaml
doctrine:
    orm:
        auto_generate_proxy_classes: false
        metadata_cache_driver:
            type: pool
            pool: doctrine.system_cache_pool
        query_cache_driver:
            type: pool
            pool: doctrine.system_cache_pool
        result_cache_driver:
            type: pool
            pool: doctrine.result_cache_pool

framework:
    cache:
        pools:
            doctrine.result_cache_pool:
                adapter: cache.app
            doctrine.system_cache_pool:
                adapter: cache.system
  1. Create a controller that uses a Doctrine\ORM\Query with a paginator (i.e. knplabs/knp-paginator-bundle).

  2. Set the environment to prod in .env (APP_ENV=prod and APP_DEBUG=0).

  3. Make requests on the controller and watch opcache_get_status()['memory_usage']['wasted_memory'] increase each time until OPCache is full and resets itself.

The expireQueryCache flag is always set to true here:

$whereInQuery->expireQueryCache();

This makes Doctrine reparse the DQL each time:

if (! $this->expireQueryCache && $cacheItem->isHit()) {
$cached = $cacheItem->get();
if ($cached instanceof ParserResult) {
// Cache hit.
$this->parserResult = $cached;
return $this->parserResult;
}
}
// Cache miss.
$parser = new Parser($this);

Then Symfony will recreate the exact same file in its cache in var/cache/prod/pools/, invalidate and recompile it into OPCache:
https://github.com/symfony/cache/blob/7d8415956df68c8dcbc9468e119945e39bacead1/Adapter/PhpFilesAdapter.php#L254-L259

Expected behavior

The OPCache wasted_memory doesn't increase on each request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions