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

Regression related to Improve lazy ghost performance by avoiding self-referencing closure #11455

Closed
raziel057 opened this issue May 15, 2024 · 7 comments · Fixed by #11475
Closed

Comments

@raziel057
Copy link
Contributor

raziel057 commented May 15, 2024

Bug Report

Q A
BC Break yes
Version 2.19.3

Summary

From the following commit of doctrine/orm 2.19.3 I got a OutOfMemoryError when trying to clone an entity that contains a blob value: 9d1a497

If I revert this change I have no issue and the Memory is low: less than 4Mo but when I apply the change, even if I allocate 2G of memory I got the OutOfMemoryError .

Current behavior

Infinite memory rise which leads to an OutOfMemoryError.

How to reproduce

namespace App\Entity;

...

#[ORM\Entity(repositoryClass: ResourceFileRepository::class)]
class ResourceFile
{

    #[Groups(['read'])]
    #[ORM\Id]
    #[ORM\Column(name: 'ID', type: 'integer', nullable: false)]
    #[ORM\GeneratedValue(strategy: 'IDENTITY')]
    private ?int $id = null;

    ...

    /**
     * @var string|resource
     */
    #[ORM\Column(name: 'VALUE', type: 'blob', nullable: false)]
    private mixed $content = null;

    public function getCopy() : self
    {
        return clone $this;
    }
    
    public function __clone()
    {
        if ($this->id) {
            $this->id = null;
        }
    }
}

As soon as I call getCopy(); I got an OutOfMemoryError:

$copy = $formDefinition->getLogo()->getCopy();

image

Please note that I have no issue if I call $formDefinition->getLogo()->getContent() to load the resource before calling $formDefinition->getLogo()->getCopy() :

dump("Initial Memory Used: ".round(memory_get_usage() / (1024*1024), 1)." MB");

$formDefinition = $this->em->getRepository(FormDefinition::class)->find($id);

dump($formDefinition->getLogo()->getContent());
dump("Memory Used before getCopy: ".round(memory_get_usage() / (1024*1024), 1)." MB");

$copy = $formDefinition->getLogo()->getCopy();

dump("Memory Used after getCopy: ".round(memory_get_usage() / (1024*1024), 1)." MB");

image

Expected behavior

Just clone the entity.

@raziel057
Copy link
Contributor Author

@nicolas-grekas Can you please consider this issue as you created the commit 9d1a497

If you need more information or to test something I'm available.

@nicolas-grekas
Copy link
Member

A small repo with instructions to reproduce would help a lot 🙏

@raziel057
Copy link
Contributor Author

I tried to create a small / simple reproducer, but could notice the issue is also related to the number of elements I have in the ResourceFile table in database. If I reduce the number of elements I don't get the MemoryLimitError.

I also detected that I got the error if I load the parent entity. For example in the following sample The formDefinition entity contains a logo (ResourceFile id 24163). If I comment the first line I don't have any Memory issue, but if I uncomment it the memory issue happen.

$formDefinition = $entityManager->getRepository(FormDefinition::class)->find(3829);
$resourceFile = $entityManager->getRepository(ResourceFile::class)->find(24163);

$copy = clone $resourceFile;

Here is the debug:

image

And at some point a query is done without restricting on ID:

image

If in clone method of ResouyrceFile I remove the following code, I don't have any issue and no query are triggered:

    if ($this->creationDate) {
        $this->creationDate = null;
    }

image

image

The code is not very easy to read so I can't provide more information for now.

@raziel057
Copy link
Contributor Author

@nicolas-grekas Here is a reproducer:

git clone https://github.com/raziel057/demo.git -b blob-issue
cd demo/
composer install
vendor/bin/simple-phpunit

Result

image

Downgrade to doctrine/orm:2.19.2 and rerun phpunit:

composer require doctrine/orm:2.19.2
vendor/bin/simple-phpunit

image

As you can see in the first result the query doesn't contain the where restriction. That's why that was leading to an OutOfMemoryError in my case as I have a lot of entities in my table.

Can you please have a look now?

@nicolas-grekas
Copy link
Member

Thanks for the reproducer. I already spotted a bug but not the one you reported :) Stay tuned.

@raziel057
Copy link
Contributor Author

Nice 👍 thanks

@nicolas-grekas
Copy link
Member

This should be fixed by #11475

@greg0ire greg0ire closed this as completed Jun 1, 2024
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

Successfully merging a pull request may close this issue.

3 participants