Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple calls to Cache::get within while loop causing incremental memory leak #54095

Open
sts-ryan-holton opened this issue Jan 6, 2025 · 4 comments

Comments

@sts-ryan-holton
Copy link
Contributor

sts-ryan-holton commented Jan 6, 2025

Laravel Version

11.35.1

PHP Version

8.3.8

Database Driver & Version

MySql 8

Description

Multiple calls within while (true) loop to Cache::get() is causing incremental memory consumption (leak) when called from a custom artisan command ran within the terminal. See attached screenshots:

I'm using Redis as my cache driver locally here and in production. I'm using Laravel telescope locally.

Without the Cache::get block

Screenshot 2025-01-06 at 17 25 00

/**
 * Execute the console command.
 */
public function handle(): int
{
    $lastRestart = Cache::get('statistic_aggregates:ingest:restart');

    while (true) {
        dump(memory_get_usage() / (1024 * 1024));

        // if ($lastRestart !== Cache::get('statistic_aggregates:ingest:restart')) {
        //     Cache::forget('statistic_aggregates:ingest:restart');

        //     return self::SUCCESS;
        // }

        Sleep::for(1)->second();
    }
}

With the Cache::get block

Screenshot 2025-01-06 at 17 26 00

/**
 * Execute the console command.
 */
public function handle(): int
{
    $lastRestart = Cache::get('statistic_aggregates:ingest:restart');

    while (true) {
        dump(memory_get_usage() / (1024 * 1024));

        if ($lastRestart !== Cache::get('statistic_aggregates:ingest:restart')) {
            Cache::forget('statistic_aggregates:ingest:restart');

            return self::SUCCESS;
        }

        Sleep::for(1)->second();
    }
}

Steps To Reproduce

  1. Create a simple artisan command and run it from the command line with a while loop to Redis

Additionally, I have tried adding the following block of code to my project and calling it:

/**
 * Schedule Telescope to store entries if enabled.
 */
protected function ensureTelescopeEntriesAreCollected(): void
{
    if ($this->laravel->bound(\Laravel\Telescope\Contracts\EntriesRepository::class)) {
        \Laravel\Telescope\Telescope::store($this->laravel->make(\Laravel\Telescope\Contracts\EntriesRepository::class));
    }
}

Still creating a memory leak after 10 seconds.

Additional context

I've just tried some other things, replacing dump() with echo, still get the same memory leak.

Interestingly the problem doesn't happen when simply echoing other facades like: str()->random(32) or now()

@cosmastech
Copy link
Contributor

Do you have the same issue if you disable telescope?

@sts-ryan-holton
Copy link
Contributor Author

@cosmastech Interestingly in a fresh install of Laravel, with Telescope, the problem still occurs. Turning Telescope off in this project and the memory doesn't leak.

In a much larger project with Telescope turned off, the memory is still leaking.

I even tried calling ensureTelescopeEntriesAreCollected but no luck? Maybe there's another way to detect and collect telescope entries if telescope is on?

@timacdonald
Copy link
Member

timacdonald commented Jan 6, 2025

I would garbage collect, via gc_collect_cycles(), before calling memory_get_usage() and see if there are any changes.

I would also recommend turning off events to see if that is where the problem lies. You can do this by specifying "events" => false in the cache driver's config.

@sts-ryan-holton
Copy link
Contributor Author

I'll give that a shot. I did try the garbage collection but it didn't return any cycles. Garbage collection was enabled when I checked the gc enabled method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants