Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

findFirst memory leak

Hello,

I need to iterate 2kk db records.

I simplified my code to this:

<?php

foreach ($videoIds as $videoId) {
            $video = null;
            $video = Video::findFirst($videoId->id);
            echo 'after memory usage: ' . memory_get_usage();
            echo PHP_EOL;
            gc_collect_cycles();

And I get:

after memory usage: 275166496
after memory usage: 275176504
after memory usage: 275186472
after memory usage: 275196216
after memory usage: 275206480
after memory usage: 275216920
after memory usage: 275226872
after memory usage: 275236368
after memory usage: 275246720
after memory usage: 275256296
after memory usage: 275266128

It means, each findFirst appends ~10kb to memory. All fields in model are defined as public. As you see in my code, I try to nullfy and gc collect, but it doesn't helps to me.

I tried to disable snapshot and dynamic update, but it didn't helped:

<?php

class Model extends PhalconModel
{
    public function initialize()
    {
        $this->keepSnapshots(false);
        $this->useDynamicUpdate(false);
    }
}

Any ideas?

Regards

What phalcon version you are using? Does doing Phalcon\Mvc\Model\Query::clean helps?

Fedora 27
PHP 7.1.17
Phalcon version 3.3.2 compiled from source

Just tried Query::clean(). It didn't helped :(

Updated code looks:

<?php

foreach ($videoIds as $videoId) {
            $video = null;
            $video = Video::findFirst($videoId->id);
            echo 'after memory usage: ' . memory_get_usage();
            echo PHP_EOL;
            gc_collect_cycles();
            \Phalcon\Mvc\Model\Query::clean();
}

Just updated to phalcon 3.4.0 and it still has leaks.



78.9k

PDO has some issues when it fetches more than 10k results, and Model::find does not add any limits whats so ever

try to use model manager + pagination and loop trough all records with a 9k limit per fetch and see it is still the same

But he fetches only one record each time.



17.5k
Accepted
answer

Thank you for responses. I found another topic: findFirst allowed memory size exhausted

So binding helped me. Actually I replaced findFirst($id) to findFirstById($id).

edited May '18

Oh, this is really weird, findFirst($id) should actually do this already like search by primary key using binding. We will need to invesitgate it anyway.

Thank you for responses. I found another topic: findFirst allowed memory size exhausted

So binding helped me. Actually I replaced findFirst($id) to findFirstById($id).

It's a better idea to explicitly use the findFirstBy<col> syntax.

I have spent half a day debugging a findFirst($id) call, because it always returned the same row. It turned out that the $id variable was always null, so it simply returned the first record in the table.