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 in RelationController with bigger datasets #3969

Closed
viamage opened this issue Dec 7, 2018 · 1 comment
Closed

Memory Leak in RelationController with bigger datasets #3969

viamage opened this issue Dec 7, 2018 · 1 comment

Comments

@viamage
Copy link
Contributor

viamage commented Dec 7, 2018

Expected behavior

RelationController supports big related datasets of related models without memory leaks.

Actual behavior

On example of HasMany relation, with around 100k related records php eats huge amounts of RAM when trying to access controller.

Reproduce steps

Seed any HasMany relation with a big dataset, setup relation controller for parent and try to access parent model in backend.

To make things easier I prepared simple plugin - https://github.com/viamage/relationsbug

It will create Category and Products models, will seed Products with 100 000 records and provide basic controller. Product is quite simple model with some name,slug, some text in description and metadata.

Debugging with:

October/Rain/Database/Relations/HasMany, line 78:

    public function getSimpleValue()
    {
        ini_set('memory_limit', '2048M');
        $value = null;
        $relationName = $this->relationName;

        if ($relation = $this->parent->$relationName) {
            $value = $relation->pluck($this->localKey)->all();
        }
        dd(memory_get_peak_usage() / 1024 / 1024);
        return $value;
    }

PHP takes 1300 MB memory to load this, thus will crash on most environments.

October build

443

Possible solution

If I change line 84 to call QueryBuilder instead of making collection to pluck later:

    public function getSimpleValue()
    {
        $value = null;
        $relationName = $this->relationName;

        if ($relation = $this->parent->$relationName()) {
            $value = $relation->pluck($this->localKey)->all();
        }

        return $value;
    }

RAM usage drops from 1300MB to 64 MB and all works as expected (is obviously as slow as it was without (), because of ->count() methods, but we can't avoid that I guess).

I am not sure if it makes sense to create Collection here if we need it only to pluck and thus create array immediately after? Are you open to accept PR that would resolve this?

Or is there some other way to solve this without touching Rain library?

@LukeTowers
Copy link
Contributor

@viamage I would accept a PR to fix this

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

No branches or pull requests

2 participants