phalcon / cphalcon

High performance, full-stack PHP framework delivered as a C extension.
https://phalcon.io
BSD 3-Clause "New" or "Revised" License
10.77k stars 1.97k forks source link

[BUG]: Model Validation Leaks Memory #16566

Open ALameLlama opened 5 months ago

ALameLlama commented 5 months ago

Describe the bug On a new phalcon project Trying to create models in a loop and the model has a validation function will leak memory

To Reproduce I set up a user model and then added this like in the example

    public function validation()
    {
        $validator = new Validation();

        $validator->add(
            'email',
            new Uniqueness(
                [
                    'message' => 'The customer email must be unique',
                ]
            )
        );

        return $this->validate($validator);
    }

Created a loop like this

        $count = 100;
        for ($i = 0; $i <= $count; $i++) {
            $before = microtime(true);

            $user = new Users([
                'firstname' => 'John',
                'lastname' => 'Doe',
                'password' => 'securepassword',
                'is_active' => true,
            ]);

        $user->create();

            $after = microtime(true);

            echo sprintf(
                'Took %s seconds. Used %s memory',
                round($after - $before, 4),
                round(((memory_get_usage() / 1024) / 1024), 4) . 'M'
            ) . PHP_EOL;
        }

Over each model it's still holding a refereance to something

Took 0.0199 seconds. Used 1.6799M memory
Took 0.0182 seconds. Used 1.6803M memory
Took 0.0185 seconds. Used 1.6806M memory
Took 0.0182 seconds. Used 1.681M memory
...
Took 0.0179 seconds. Used 1.7147M memory
Took 0.0181 seconds. Used 1.715M memory
Took 0.0181 seconds. Used 1.7154M memory
Took 0.0185 seconds. Used 1.7158M memory
Took 0.0181 seconds. Used 1.7161M memory
Took 0.0187 seconds. Used 1.7165M memory

Expected behavior I'm pretty sure this should get GC'd I checked with gc_status() and it looks like the PHP garbage collector is running but it's not freeing this memory

Details

noone-silent commented 5 months ago

I think I reported this Bug on the discord. It's not the validation, it's the model manager, who keeps a copy of every model and this grows unlimited

maxgalbu commented 4 months ago

@noone-silent is this confirmed or it's just a guess? Do you know if someone is looking into it? I'm having memory leak problems in a forever-running CLI script

noone-silent commented 4 months ago

Yes, this is where you can experience it. We had the same problem, our container crashed, because the memory was only growing. I debugged it and found out, that the ModelsManager keeps every Model and the relations in memory.

So it is confirmed on our side. We overwrite the models to always use a new ModelsManager

    public function initialize(): void
    {
        // Only run this on the first initialization.
        // When there are non critical tasks, place it outside of this if.
        if ($this->modelsManager instanceof Manager === false) {
            $this->useDynamicUpdate(true);
            $this->modelsManager = new Manager();
            $this->modelsManager->setDI($this->getDI());
        }
    }

Also you need to overwrite the getRelated and postSaveRelatedRecords Methods. This solved our memory Problem.

noone-silent commented 4 months ago

@maxgalbu If this fixes your issues too, please post it here.

maxgalbu commented 4 months ago

@noone-silent actually, it wasn't models that were leaking for me, I did find another memory leak: https://github.com/phalcon/cphalcon/issues/16571