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

Memory leak - binds not being cleared after find() #1604

Closed
Martin-4Spaces opened this issue Dec 11, 2018 · 5 comments
Closed

Memory leak - binds not being cleared after find() #1604

Martin-4Spaces opened this issue Dec 11, 2018 · 5 comments

Comments

@Martin-4Spaces
Copy link

Version: Alpha.4.

Memory usage keep increasing when saving a many models. Memory usage raises above 128MB when saving 1.000 models with 10 properties.
I tried setting $skipValidation = true and it fixed the issue. Now memory usage is ~2MB. I do not have any validation rules.

Looks like a memory leak in the validation part.
Sorry, I do not have further details.

@Martin-4Spaces
Copy link
Author

I will investigate and return with more details.

@Martin-4Spaces
Copy link
Author

Aha!
Ofc. It has nothing to do with the validation function. :-)
My issue is caused by binds on model not being cleared after find().
I use the same model-instance to fetch many entities. Each time I call find with an id, the is is saved to the binds array. And the array just keeps growing and growing :/

@Martin-4Spaces Martin-4Spaces changed the title Memory leak - Model validation Memory leak - binds not being cleared after find() Dec 11, 2018
@Paradinight
Copy link

How about an example code?

@Martin-4Spaces
Copy link
Author

Here is an example project. CI4Issue.zip

Model

class TrashModel extends \CodeIgniter\Model {

    public $table = 'trash';
    public $id;
    public $content;

}

Controller

    public function exampleWithMemoryLeak()
    {
        $total = 2500; // ~Max for 120MB
        $printInterval = 100;

        $model = new TrashModel();

        for($i = 0 ; $i < $total ; $i++) {

            $model->find($i);

            if(! ($i % $printInterval)) {
                Data::memory("$i items");
                Data::debug(serialize($model));
            }

        }

        $this->response->setJSON(Data::getStore());
        $this->response->send();
    }

Data::memory and Data::debug is a debugging tool I use.
Unzip the project. Add your .env file and database connection. Create a table:

CREATE TABLE `trash` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `content` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Check the output of /home and you will see the memory usage increase over time. You can also see the serialised $model and that binds grow for every find on the same model.

Check the output of /home/exampleWithoutMemoryLeak and you will that memory usage is unchanged.

    public function exampleWithoutMemoryLeak()
    {
        $total = 10000;
        $printInterval = 100;

        for($i = 0 ; $i < $total ; $i++) {

            $model = new TrashModel();
            $model->find($i);

            if(! ($i % $printInterval))
                Data::memory("$i items");

        }

        $this->response->setJSON(Data::getStore());
        $this->response->send();
    }

@lonnieezell
Copy link
Member

Just pushed a fix. Let me know if you're running into issues with it.

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

No branches or pull requests

3 participants